select all triples, indicating named graph if relevant
Asked Answered
L

5

5

Let's say I make the following insertions into my GraphDB 8.3 triplestore:

PREFIX : <http://example.com/>
insert data { :hello a :word }

and

PREFIX : <http://example.com/>
insert data { graph :farewells { :goodbye a :word }}

now, if I ask

select * where {
    graph ?g {
        ?s ?p ?o .
    } 
}

I only get

+--------------------------------+------------------------------+---------------------------------------------------+---------------------------+
|               ?g               |              ?s              |                        ?p                         |            ?o             |
+--------------------------------+------------------------------+---------------------------------------------------+---------------------------+
| <http://example.com/farewells> | <http://example.com/goodbye> | <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> | <http://example.com/word> |
+--------------------------------+------------------------------+---------------------------------------------------+---------------------------+

I can obviously get both "triples about words" with the following, but then the named-graph membership is not shown

select * { ?s ?p ?o }

How can I write a query that retrieves both triples about words and indicates that { :goodbye a :word } comes from graph :farewells ?

Lalitta answered 26/9, 2017 at 21:23 Comment(0)
B
1

In case you use have to use implicit triples in other part of the query, and in case a FILTER NOT EXISTS causes performance issues.

Then you can query what you inserted without graph clause with GRAPH <http://rdf4j.org/schema/rdf4j#nil>

In your example, you could use the query:

SELECT * 
WHERE {
   { GRAPH ?g { ?s ?p ?o } }
   UNION { GRAPH <http://rdf4j.org/schema/rdf4j#nil> { ?s ?p ?o } }
}

returns:

+------------------------------------+----------+-----------+-------+
| ?g                                 | ?s       | ?p        | ?o    |
+------------------------------------+----------+-----------+-------+
|                                    | :hello   | rdf:type  | :word |
| :farewells                         | :goodbye | rdf:type  | :word |
+------------------------------------+----------+-----------+-------+

At least it works in my free graphDB GraphDB 10.2.0 • RDF4J 4.2.2

Edit: I found one "better":

SELECT * 
WHERE {
    VALUES ?g {UNDEF <http://rdf4j.org/schema/rdf4j#nil>}
    GRAPH ?g { ?s ?p ?o } 
}

It returns:

+------------------------------------+----------+-----------+-------+
| ?g                                 | ?s       | ?p        | ?o    |
+------------------------------------+----------+-----------+-------+
|  rdf4j:nil                         | :hello   | rdf:type  | :word |
| :farewells                         | :goodbye | rdf:type  | :word |
+------------------------------------+----------+-----------+-------+
Borders answered 24/5 at 13:52 Comment(0)
S
8

You can do something along these lines:

SELECT * 
WHERE {
   { GRAPH ?g { ?s ?p ?o } }
   UNION
   { ?s ?p ?o .
     FILTER NOT EXISTS { GRAPH ?g { ?s ?p ?o } } 
   }
}

The first part of the union selects all triples in named graphs. The second part grabs all triples in the default graph, explicitly excluding patterns that occur in a named graph.

Sieve answered 27/9, 2017 at 0:8 Comment(0)
R
5

In GraphDB, you could use pseudographs for this purpose, i. e. <http://www.ontotext.com/explicit> (it seems you are not using inferencing).

Try this query:

SELECT * FROM NAMED <http://www.ontotext.com/explicit>
{ GRAPH ?g { ?s ?p ?o } }

The result should be:

+------------------------------------+----------+-----------+-------+
| ?g                                 | ?s       | ?p        | ?o    |
+------------------------------------+----------+-----------+-------+
| <http://www.ontotext.com/explicit> | :hello   | rdf:type  | :word |
| :farewells                         | :goodbye | rdf:type  | :word |
+------------------------------------+----------+-----------+-------+

For comparison, note that

SELECT * FROM NAMED <http://www.openrdf.org/schema/sesame#nil>
{ GRAPH ?g { ?s ?p ?o } }

will return only

+------------------------------------+----------+-----------+-------+
| ?g                                 | ?s       | ?p        | ?o    |
+------------------------------------+----------+-----------+-------+
| <http://www.ontotext.com/explicit> | :hello   | rdf:type  | :word |
+------------------------------------+----------+-----------+-------+
Remise answered 27/9, 2017 at 10:4 Comment(0)
S
1

Short "answer": avoid putting data into the default graph in GraphDB (and other triple stores with a "virtual" default graph which is just a UNION of all named graphs)

Background: GraphDB decided to define the default graph as the union of all named graphs and the default graph. This behaviour is not backed by the SPARQL semantics specification, but is implementation-specific behaviour.

So you really have three options:

  1. Use FILTER NOT EXISTS or MINUS as explained by Jeen Broekstra. This can have a serious negative impact on query performance.

  2. Use the GraphDB pseudographs as exemplified by Stanislav Kralin. This option makes your queries (and your system) dependent on GraphDB -- you can not change the SPARQL engine later, without adapting your queries.

  3. Avoid putting data into the default graph. You might define "your own" default graph, e.g. call it http://default/, and put it in the SPARQL FROM clause.

Other triple stores allow to enable/disable this feature. I couldn't find a switch in the documentation of GraphDB. Otherwise this would be the 4th, and my preferred, option.

Silverman answered 28/9, 2017 at 10:55 Comment(3)
This behaviour is allowed: w3.org/TR/2013/REC-sparql11-service-description-20130321/…Remise
@StanislavKralin yes, it is allowed as part of the service description. But the semantics of SPARQL is not defined in this way. While I understand the purpose of this feature, it might confuse SPARQL users. I clarified the answer accordingly.Silverman
Just a minor (late) correction: the GraphDB behavior is backed by the SPARQL specification, which does not favor one interpretation of what the default graph contains over another.Sieve
B
1

In case you use have to use implicit triples in other part of the query, and in case a FILTER NOT EXISTS causes performance issues.

Then you can query what you inserted without graph clause with GRAPH <http://rdf4j.org/schema/rdf4j#nil>

In your example, you could use the query:

SELECT * 
WHERE {
   { GRAPH ?g { ?s ?p ?o } }
   UNION { GRAPH <http://rdf4j.org/schema/rdf4j#nil> { ?s ?p ?o } }
}

returns:

+------------------------------------+----------+-----------+-------+
| ?g                                 | ?s       | ?p        | ?o    |
+------------------------------------+----------+-----------+-------+
|                                    | :hello   | rdf:type  | :word |
| :farewells                         | :goodbye | rdf:type  | :word |
+------------------------------------+----------+-----------+-------+

At least it works in my free graphDB GraphDB 10.2.0 • RDF4J 4.2.2

Edit: I found one "better":

SELECT * 
WHERE {
    VALUES ?g {UNDEF <http://rdf4j.org/schema/rdf4j#nil>}
    GRAPH ?g { ?s ?p ?o } 
}

It returns:

+------------------------------------+----------+-----------+-------+
| ?g                                 | ?s       | ?p        | ?o    |
+------------------------------------+----------+-----------+-------+
|  rdf4j:nil                         | :hello   | rdf:type  | :word |
| :farewells                         | :goodbye | rdf:type  | :word |
+------------------------------------+----------+-----------+-------+
Borders answered 24/5 at 13:52 Comment(0)
L
1

As of 2024-06-24, all of the posted answers work for the provided dataset in GraphDB 10.5.0.

I haven't done any performance assessment, which would presumably require a larger dataset.

I especially appreciate Stefan Bischof's advice about the default graph, the list, and the resulting discussion.

But for my needs (and without any performance testing yet), I am going to use the

VALUES ?g {UNDEF <http://rdf4j.org/schema/rdf4j#nil>}

answer from Aymeric PICOU

Lalitta answered 24/6 at 18:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.