- From: Axel Polleres <axel.polleres@deri.org>
- Date: Tue, 19 May 2009 12:45:02 +0100
- To: 'RDF Data Access Working Group' <public-rdf-dawg@w3.org>
This completes Action-20: http://www.w3.org/2009/sparql/track/actions/20 I promised in the F2F to send a use case to the list on using nested CONSTRUCT queries in FROM clauses. Here we go (BTW: we should talk about where/how to collect these use cases on the wiki) ===================================================================== The scenario is as follows. You have some RDF representation about publications available that uses dc:creator links to link publications to the names of their authors. Graph <g>: <http://ex.org/papers#p1> dc:creator "Alice" . <http://ex.org/papers#p1> dc:creator "Bob" . <http://ex.org/papers#p1> dc:creator "Charles" . We want to translate that data to FOAF extracting social network informaiton saying that each two persons who co-authored an article know each other. We have to use blank nodes for denoting authors, since we have only their name. The naive query CONSTRUCT { _:a foaf:knows _:b . _:a foaf:name ?n1 . _:b foaf:name ?n2 . } FROM <g> WHERE { ?p dc:creator ?n1 . ?p dc:creator ?n2 . FILTER ( ?n1 != ?n2 ) } wouldn't work as desired, because the solution would assign different blank nodes for eaach solution, loosing the co-reference between authors of the same paper: _:a1 foaf:knows _:b1. _:a1 foaf:name "Alice". _:b1 foaf:name "Bob". _:a2 foaf:knows _:b2. _:a2 foaf:name "Alice". _:b2 foaf:name "Charles". _:a3 foaf:knows _:b3. _:a3 foaf:name "Bob". _:b3 foaf:name "Charles". _:a4 foaf:knows _:b4. _:a1 foaf:name "Bob". _:b1 foaf:name "Alice". _:a5 foaf:knows _:b5. _:a2 foaf:name "Charles". _:b2 foaf:name "Alice". _:a6 foaf:knows _:b6. _:a3 foaf:name "Charles". _:b3 foaf:name "Bob". The following query, using nested CONSTRUCTs in the FROM clause, solves this problem by creating a bnode for each paper-author-pair in the first step and only in a second step creating the foaf:knows links between these blank noedes: CONSTRUCT { ?a knows ?b . ?a foaf:name ?aname . ?b foaf:name ?bname . } FROM { CONSTRUCT { _:a foaf:name ?n . ?p aux:hasAuthor _:a . } FROM <g> WHERE { ?p dc:creator ?n . } } WHERE { ?p aux:hasAuthor ?a . ?a foaf:name ?aname . ?p aux:hasAuthor ?b . ?b foaf:name ?bname . FILTER ( ?a != ?b ) } Result: _:a1 foaf:knows _:a2. _:a1 foaf:name "Alice". _:a2 foaf:name "Bob". _:a1 foaf:knows _:a3. _:a1 foaf:name "Alice". _:a3 foaf:name "Charles". _:a2 foaf:knows _:a3. _:a2 foaf:name "Bob". _:a3 foaf:name "Charles". _:a2 foaf:knows _:a1. _:a2 foaf:name "Bob". _:a1 foaf:name "Alice". _:a3 foaf:knows _:a1. _:a3 foaf:name "Charles". _:a1 foaf:name "Alice". _:a3 foaf:knows _:a2. _:a3 foaf:name "Charles". _:a2 foaf:name "Bob". As easily observed, the second result preserves the coreference between blank nodes and names of authors of the same papers. =================================================================
Received on Tuesday, 19 May 2009 11:45:45 UTC