The Jena users list is at [email protected].
> CONSTRUCT {
> ?s ?p0 ?o0 .
> ?o0 ?p1 ?o1 .
> ?o1 ?p2 ?o2 .
> ?o2 ?p3 ?o3 .
> ?o3 ?p4 ?o4 .
> } WHERE
> {
> OPTIONAL { GRAPH <http://ao.com/namedGraph/g> { ?s ?p0 ?o0 }}
> OPTIONAL { GRAPH <http://ao.com/namedGraph/g> { ?o0 ?p1 ?o1 }}
> OPTIONAL { GRAPH <http://ao.com/namedGraph/g> { ?o1 ?p2 ?o2 }}
> OPTIONAL { GRAPH <http://ao.com/namedGraph/g> { ?o2 ?p3 ?o3 }}
> OPTIONAL { GRAPH <http://ao.com/namedGraph/g> { ?o3 ?p4 ?o4 }}
Consider what happens if { ?s ?p0 ?o0 } matches, then { ?o0 ?p1 ?o1 }
does not.
{ ?o1 ?p2 ?o2 } is not attached to ?s via ?o1 so it matches the whole graph.
Your description would be better written as:
GRAPH <http://ao.com/namedGraph/g> {
?s ?p0 ?o0
OPTIONAL { ?o0 ?p1 ?o1
OPTIONAL { ?o1 ?p2 ?o2
OPTIONAL { ?o2 ?p3 ?o3
OPTIONAL { ?o3 ?p4 ?o4 }
}}}
}
Andy
On 25/04/17 04:02, Dimov, Stefan wrote:
… on the other hand, DESCRIBE works correctly ☺:
DESCRIBE ?s
{
OPTIONAL { GRAPH <http://ao.com/namedGraph/g> { ?s ?p0 ?o0 }}
You don't need the rest - only ?s matters in the DESCRIBE
OPTIONAL { GRAPH <http://ao.com/namedGraph/g> { ?o0 ?p1 ?o1 }}
OPTIONAL { GRAPH <http://ao.com/namedGraph/g> { ?o1 ?p2 ?o2 }}
OPTIONAL { GRAPH <http://ao.com/namedGraph/g> { ?o2 ?p3 ?o3 }}
OPTIONAL { GRAPH <http://ao.com/namedGraph/g> { ?o3 ?p4 ?o4 }}
FILTER (STR(?s) = "http://ao.com/uc/example")
}
It returns only the object specified by the filter.
Correct me if I’m wrong, but seems there’s a bug in the CONSTRUCT
implementation …
S.
From: Stefan Dimov <[email protected]>
Date: Monday, April 24, 2017 at 7:45 PM
To: "[email protected]" <[email protected]>
Subject: Unexpected SPARQL CONSTRUCT output
I have in my named graph only two json-ld objects – “example” and example1”.
I have this query (filter is ‘example1’):
CONSTRUCT {
?s ?p0 ?o0 .
?o0 ?p1 ?o1 .
?o1 ?p2 ?o2 .
?o2 ?p3 ?o3 .
?o3 ?p4 ?o4 .
} WHERE
{
OPTIONAL { GRAPH <http://ao.com/namedGraph/g> { ?s ?p0 ?o0 }}
OPTIONAL { GRAPH <http://ao.com/namedGraph/g> { ?o0 ?p1 ?o1 }}
OPTIONAL { GRAPH <http://ao.com/namedGraph/g> { ?o1 ?p2 ?o2 }}
OPTIONAL { GRAPH <http://ao.com/namedGraph/g> { ?o2 ?p3 ?o3 }}
OPTIONAL { GRAPH <http://ao.com/namedGraph/g> { ?o3 ?p4 ?o4 }}
FILTER (STR(?s) = "http://ao.com/uc/example1")
}
and it returns me both ‘example’ and ‘example1’:
<http://ao.com/uc/example1>
<http://ao.com/propOf> [ <http://ao.com/object> "w4" ;
<http://ao.com/property> [
<http://ao.com/g/term>
[ <http://ao.com/order#0>
"w0" ;
<http://ao.com/order#1>
"w1" ;
<http://ao.com/order#2>
"w2" ;
<http://ao.com/order#3>
"w3"
] ]
] .
<http://ao.com/uc/example>
<http://ao.com/propOf> [ <http://ao.com/object> "w5" ;
<http://ao.com/property> [
<http://ao.com/g/term>
[ <http://ao.com/order#0> "
w0" ;
<http://ao.com/order#1>
"w1" ;
<http://ao.com/order#2>
"w" ;
<http://ao.com/order#3>
"w4"
] ]
] .
not just “example1” as one would expect.
If I change the filter to “example”, again I get both ‘example’ and ‘example1’.
If I change the filter to something else (i.e. – non-existent), I get an empty
result. That means, the filter works, but not quite as expected.
More interesting – if I reduce the depth of the query:
CONSTRUCT {
?s ?p0 ?o0 .
?o0 ?p1 ?o1 .
?o1 ?p2 ?o2 .
} WHERE
{
OPTIONAL { GRAPH <http://ao.com/namedGraph/g> { ?s ?p0 ?o0 }}
OPTIONAL { GRAPH <http://ao.com/namedGraph/g> { ?o0 ?p1 ?o1 }}
OPTIONAL { GRAPH <http://ao.com/namedGraph/g> { ?o1 ?p2 ?o2 }}
FILTER (STR(?s) = "http://ao.com/uc/example")
}
it returns me (exactly as expected) only the object that matches the filter:
<http://ao.com/uc/example1>
<http://ao.com/propOf> [ <http://ao.com/object> "w4" ;
<http://ao.com/property> [
<http://ao.com/g/term>
[] ]
] .
Why is that? Is there any way to work around this?
Stefan