SPARQL multi graph request and sort (Virtuoso 7)
SPARQL multi graph request and sort (Virtuoso 7)
Is it possible to easily make a CONSTRUCT
request where I would be able to check data in different graphs AND sort them by "graph preference"?
CONSTRUCT
Let's say I sell products. For each product, I may have different suppliers, so that my setup would look like this:
graph:supplier1
<data/product/1> <http://purl.org/goodrelations/v1#hasCurrencyValue> "10" .
graph:supplier2
<data/product/1> <http://purl.org/goodrelations/v1#hasCurrencyValue> "8" .
<data/product/2> <http://purl.org/goodrelations/v1#hasCurrencyValue> "5" .
For each product specification, I want it from (graph) supplier1
, then from (graph) supplier2
if not found in (graph) supplier1
.
supplier1
supplier2
supplier1
This is what I've come up to:
CONSTRUCT
{
<data/product/1> ?p ?o .
}
WHERE
{
GRAPH <graph:supplier1>
{
OPTIONAL
{
<data/product/1> ?p1 ?o1 .
}
}
GRAPH <graph:supplier2>
{
OPTIONAL
{
<data/product/1> ?p2 ?o2 .
}
}
BIND (IF (BOUND(?p1), ?p1, IF (BOUND(?p2), ?p2, UNDEF)) AS ?p)
BIND (IF (BOUND(?o1), ?o1, IF (BOUND(?o2), ?o2, UNDEF)) AS ?o)
}
It does work pretty nice if I know what I'm looking for. Now if I consider:
CONSTRUCT
{
<data/product/1> ?p ?o . ?o ?cp ?co
}
WHERE
{
GRAPH <graph:supplier1>
{
OPTIONAL
{
<data/product/1> ?p1 ?o1 .
OPTIONAL { ?o1 ?cp1 ?co1 . }
}
}
GRAPH <graph:supplier2>
{
OPTIONAL
{
<data/product/1> ?p2 ?o2 .
OPTIONAL { ?o2 ?cp2 ?co2 . }
}
}
BIND (IF (BOUND(?p1), ?p1,IF (BOUND(?p2), ?p2, UNDEF)) AS ?p)
BIND (IF (BOUND(?o1), ?o1,IF (BOUND(?o2), ?o2, UNDEF)) AS ?o)
BIND (IF (BOUND(?cp1), ?cp1,IF (BOUND(?cp2), ?cp2, UNDEF)) AS ?cp)
BIND (IF (BOUND(?co1), ?co1,IF (BOUND(?co2), ?co2, UNDEF)) AS ?co)
}
Sometimes it doesn't work because I explicitly BIND
?o
, and ?o
may not be an Object —
BIND
?o
?o
Virtuoso RDF01 Error Bad variable value in CONSTRUCT: "1532610063"
(tag 189 box flags 0) is not a valid subject, only object of a triple
can be a literal
I don't seem to find anyone trying to sort data by "graphs" and I'm struggling trying to find an "easy" way to do it.
I've tried with SELECT
and FROM NAMED
, but you've still to manually select data from the graph you want.
SELECT
FROM NAMED
If anyone can help, it is more than welcome.
Thank you.
by the way, you should fix this phrase: "check datas in differents graphs dans sort them by "graph perefence" ?"
– AKSW
Jul 27 at 14:01
I'm also surprised that your query is working even sometimes. you only have
OPTIONAL
patterns which are left-outer joins with empty tables in your query.– AKSW
Jul 27 at 14:04
OPTIONAL
Thank you for your answer @AKSW. I don't think I can achieve what I need with union. I'll try an other way around.
– ThomasBKN
15 hours ago
You might consider
COALESCE
for your complex BIND ... IF
clauses. I found a nice example.– TallTed
15 hours ago
COALESCE
BIND ... IF
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
you can bind it once for non-literals and once for literals. both can be combined via UNION then.
– AKSW
Jul 27 at 13:58