I'm facing the problem of identification when doing automatic instanciation of triplets using SPARQL queries. Let see the problem through this example.
suppose that we have the following triplets set representing person and their weeding relation.
ns:Person rdf:type owl:Class
ns:Man rdfs:subClassOf ns:Person
ns:Woman rdfs:subClassOf ns:Person
ns:Family rdf:type owl:Class
ns:jean rdf:type ns:Man
ns:roger rdf:type ns:Man
ns:chris rdf:type ns:Woman
ns:sofy rdf:type ns:Woman
ns:chloe rdf:type ns:Woman
ns:jean ns:isMarriedWith ns:chris
ns:roger ns:isMarriedWith ns:chloe
Ok now we want to automatically build families using the rule that a family is when two person are married.
IF (ns:A ns:isMarriedWith ns:B)
THEN (ns:f rdf:type Family)
AND (ns:f ns:contains A)
AND (ns:f ns:contains B)
here is the Java code that I propose to do that upon an http sesame repository.
Repository myRepository = new HTTPRepository(serverURL, repositoryId);
myRepository.initialize();
RepositoryConnection con = myRepository.getConnection();
query = "INSERT {"
+ " ns:f0 rdf:type ns:Family ."
+ " ns:f0 ns:contains ?p ."
+ " ns:f0 ns:contains ?q ."
+ "}"
+ "WHERE { "
+ " ?p ns:isMarriedWith ?q ."
+ "}";
Update update = con.prepareUpdate(QueryLanguage.SPARQL, query);
update.execute();
Here are triplets which were inserted
ns:f0 rdf:type ns:Family
ns:f0 ns:contains ns:jean
ns:f0 ns:contains ns:chris
ns:f0 ns:contains ns:roger
ns:f0 ns:contains ns:chloe
This result is not correct, because only one family is created. The problem is that the identify of the familly instance doesn't change any time that the WHERE clause match.
How could I tune the above code in order the have the following correct response.
ns:f0 rdf:type ns:Family
ns:f0 ns:contains ns:jean
ns:f0 ns:contains ns:chris
ns:f1 rdf:type ns:Family
ns:f1 ns:contains ns:roger
ns:f1 ns:contains ns:chloe
Thank !
It's much easier to answer this type of question if you provide data and code that we can work with without having to add a whole bunch of stuff to make it complete. E.g., provide complete working RDF documents. Your data is something like this (in Turtle):
In your SPARQL query, it's not clear what
f0
is, since it's not legal SPARQL syntax, but based on your description of the problem, you've got something like the following. I've changed to aconstruct
query so that we can look at the results of the query and see the triples that are constructed, which would be the same as the triples that get inserted. This just makes it easier to see what's happening.Now, your problem is that when you run this query on that data, you get results like:
where there's one family that contains all four people, but you want a different family for each pair. The trick is to replace the constant
:f0
with a blank node, which will be unique for each match in the query. You could do this just by changing:f0
to_:f0
:but I'd prefer to use a bit more of the syntactic sugar that we have available to us and just write:
so that we have:
The results of this query contain two different families: