sparqlrdfjenafusekinamed-graphs

Querying over named graphs and union graph in Jena


I'm struggling to get a query to work in Jena. The query is composed of two parts:

This query works as intended in a handful of RDF stores, in some others it returns slightly unexpected results and in a few it doesn't work at all. Among the latter is Jena, but with Jena I'm not sure why, and if I'm doing something wrong.

The query depends on the availability of a default graph as the union of all named graphs. Jena's TDB2 can be configured to provide that with the tdb2:unionDefaultGraph true parameter and so I did (in a Docker container of stain/jena-fuseki:latest).

This is the example data:

PREFIX :   <http://ex.org> .

GRAPH :A { :A :pA :DS .}
GRAPH :B { :A :in :B .
           :A :pB :DN .}
GRAPH :C { :B :in :C .}
GRAPH :D { :C :in :D .
           :A :pD :DN .}

This is the query with both components, sub-select and main query:

PREFIX :   <http://ex.org> 

SELECT DISTINCT ?graph ?prop ?val ?nesting
# FROM <urn:x-arq:UnionGraph>
WHERE {
    BIND ( :A AS ?graph ) .
    # subquery to collect the graphs in which ?graph is nested
    { SELECT ?graph ?nesting WHERE {
        ?graph :in* ?path .
        ?path  :in+ ?nesting . 
    } }
    # attributions on graph :A in graphs in which it is nested
    GRAPH ?nesting { ?graph ?prop ?val }
    FILTER ( ?prop != :in )
} ORDER BY ?prop

# expected results
# graph     prop    val     nesting
# :A        :pB     :DN     :B   
# :A        :pD     :DN     :D   

In Jena this query doesn't return any results, neither with nor without FROM clause.

I tested the two components separately from each other. First the sub select:

PREFIX :   <http://ex.org>

SELECT DISTINCT ?graph ?nesting
FROM <urn:x-arq:UnionGraph>
WHERE {
    BIND ( :A AS ?graph ) .
    ?graph :in* ?path .
    ?path  :in+ ?nesting . 
} ORDER BY ?nesting

# expected results
# graph     nesting
# :A        :B
# :A        :C
# :A        :D

The sub-select works as expected with FROM clause, but doesn't return any results without FROM clause.

Then the main query:

PREFIX :   <http://ex.org>

SELECT DISTINCT ?graph ?prop ?val ?nesting
# FROM <urn:x-arq:UnionGraph>
WHERE {
    BIND ( :A AS ?graph ) .
    GRAPH ?nesting { ?graph ?prop ?val }
    FILTER ( ?prop != :in )
} ORDER BY ?graph ?nesting

# expected results
# graph     prop    val       nesting  
# :A        :pA     :DS       :A 
# :A        :pB     :DN       :B
# :A        :pD     :DN       :D

This query doesn't return any results with FROM clause, but works as expected without FROM clause.

So it seems that the sub-select query depends on the FROM clause to refer to the union default graph while the the main query only works without such a reference. Is that right, and if yes: there a way around this dilemma?


Solution

  • Try using GRAPH <urn:x-arq:UnionGraph>:

    PREFIX :   <http://ex.org>
    
    SELECT DISTINCT ?graph ?nesting
    WHERE {
          GRAPH <urn:x-arq:UnionGraph> {
            BIND ( :A AS ?graph ) .
            ?graph :in* ?path .
            ?path  :in+ ?nesting .
        }
    } ORDER BY ?nesting
    
    

    <urn:x-arq:UnionGraph> isn't a real named graph (e.g. counting the number of named graphs does not include it).

    The queries with a FROM clause do not work because the dataset being queried has <urn:x-arq:UnionGraph> as the default graph and it has no named graphs. GRAPH ?nesting then does not match.