Dynamically create new instances from SPARQL

59 views
Skip to first unread message

Dan Segal

unread,
Feb 12, 2021, 12:38:07 PM2/12/21
to TopBraid Suite Users
Is it possible to dynamically create a new instance based on a query result?

For example, let's say that we assert:

?s ?p ?o

We would then want to dynamically create a new instance ?s1 with a graph such as:

?s1 ?p1 ?o

I have tried a query such as the following, but this does not work without the variable ?s1 being declared in the WHERE clause:

INSERT {
?s1 a class1;
    ?p1 ?o
}

WHERE
{?s a class;
  ?p ?o}


I have also tried the following, but it returns an error "INSERT can only modify the default graph"

INSERT {
   GRAPH <urn:this_graph>
      {
?s1 a class1;
    ?p1 ?o
}
}

WHERE
{?s a class;
  ?p ?o}

Is there a way to create these new ?s1 instances automatically based on the query conditions?

Thank you!

Dan



Irene Polikoff

unread,
Feb 12, 2021, 1:32:13 PM2/12/21
to topbrai...@googlegroups.com
Please see below

On Feb 12, 2021, at 12:38 PM, Dan Segal <dan.seg...@gmail.com> wrote:

Is it possible to dynamically create a new instance based on a query result?

Yes, as long as SPARQL Update is turned on for your server. Go to the Server Configuration page in the Admin Console to make sure it is on. By default, it is off.

You can also create new instances using GraphQL. See https://www.topquadrant.com/querying-topbraid-edg-with-graphql/


For example, let's say that we assert:

?s ?p ?o

We would then want to dynamically create a new instance ?s1 with a graph such as:

?s1 ?p1 ?o

I have tried a query such as the following, but this does not work without the variable ?s1 being declared in the WHERE clause:

INSERT {
?s1 a class1;
    ?p1 ?o
}

WHERE
{?s a class;
  ?p ?o}

All variables in the INSERT must be specified/bound in the WHERE clause. You need to create a URI for ?s1 before you can use it in the insert. ?p1 is also unbound in your example.

For example, you could base it on a label and prepend the namespace. There are a number of SPARQL functions for doing this. For example:


spif:buildURI (spin:Function)

Constructs a new URI resource by inserting the existing variable bindings into a template. The template can mention variable names in curly braces, such as "my:Instance-{?index}" would create "my:Instance-42" is ?index has the value 42. As an alternative to variable names, the function can take additional arguments after the template, the variables of which can be accessed using {?1}, {?2} etc. For example: smf:buildURI("my:Instance-{?1}-{?2}", ?day, ?month) would insert day and month at places {?1} and {?2}.

Arguments

sp:arg1 (xsd:string): The URI template such as "<http://my.com/Instance-{?index}>". If the template contains a full URI, then it must be wrapped by <...>, otherwise the system will treat it as a qname.

Return type

  • Resource

spif:buildUniqueURI (spin:Function)

A variation of smf:buildURI that also makes sure that the created URI is unique in the current graph (that is, no triple contains the URI as either subject, predicate or object). This function is particularly useful for ontology mapping from a legacy data source into an RDF model.

Arguments

sp:arg1 (xsd:string): The URI template such as "<http://my.com/Instance-{?index}>". If the template contains a full URI, then it must be wrapped by <...>, otherwise the system will treat it as a qname.

Look in the TBC Help under SPARQL Functions Reference.

INSERT {
   GRAPH <urn:this_graph>
      {
?s1 a class1;
    ?p1 ?o
}
}

WHERE
{?s a class;
  ?p ?o}

Is there a way to create these new ?s1 instances automatically based on the query conditions?

Thank you!

Dan




--
You received this message because you are subscribed to the Google Groups "TopBraid Suite Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to topbraid-user...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/topbraid-users/e7312fa7-ee09-41e1-a69f-692dbdefba49n%40googlegroups.com.

Michael DeBellis

unread,
Feb 12, 2021, 1:41:47 PM2/12/21
to topbrai...@googlegroups.com
I have tried a query such as the following, but this does not work without the variable ?s1 being declared in the WHERE clause:
INSERT {
?s1 a class1;
    ?p1 ?o
}
WHERE
{?s a class;
  ?p ?o}

You can definitely insert new triples with SPARQL but all your parameters need to get bound in the WHERE clause. I don't quite understand what you are trying to do in the above expression. What would ?s1 get bound to?  There is no way for SPARQL to know. Here is a simple example from a tutorial I'm doing on SPARQL where I DELETE triples for phone numbers that aren't of the format nnn-nnn-nnnn: 

DELETE {?emp pizza:hasPhone ?badphone}
WHERE  {?emp pizza:hasPhone ?badphone.
FILTER(!regex(?badphone, "\\d{3}-\\d{3}-\\d{4}"))}

But this could also be used to assert new information. For example, if I had a property called hasVerifiedPhone for numbers that are formatted appropriately I could do (note I removed the not from the FILTER):

INSERT {?emp pizza:hasVerifiedPhone ?goodphone}
WHERE  {?emp pizza:hasPhone ?goodphone .
FILTER(regex(?goodphone , "\\d{3}-\\d{3}-\\d{4}"))}

Here is an example of a query where I bind parameters to an IRI (note: there are easier ways to do this but just to show an example of binding parameters in the WHERE and using them in the INSERT) and then insert them into the knowledge graph. I know some of the data looks bad, that is part of the tutorial, to find and transform bad and missing data, using both SPARQL and SHACL:

INSERT {?mngr a pizza:Employee;
 pizza:hasPhone "415-5554567";
 pizza:hasPhone "123-345-4567";
 pizza:ssn "321-23-4532".
?chf a pizza:Employee;
 pizza:hasPhone "415-555-1234";
 pizza:ssn "333-22-4444".
?wt1 a pizza:Employee;
 pizza:hasPhone "123-234-3434";
 pizza:ssn "123456666".
?wt2 a pizza:Employee.}
WHERE {
BIND (IRI("http://www.semanticweb.org/pizzatutorial/ontologies/2020/PizzaTutorial#Manager") AS ?mngr).
BIND (IRI("http://www.semanticweb.org/pizzatutorial/ontologies/2020/PizzaTutorial#Chef") AS ?chf).
BIND (IRI("http://www.semanticweb.org/pizzatutorial/ontologies/2020/PizzaTutorial#Waiter1") AS ?wt1).
BIND (IRI("http://www.semanticweb.org/pizzatutorial/ontologies/2020/PizzaTutorial#Waiter2") AS ?wt2).
}

Hope that helps, 
Michael


Reply all
Reply to author
Forward
0 new messages