SPARQL-query (RDFlib 6.1.1) with NOT EXIST or BIND produce ParseException - sparql

Neither (NOT) EXIST nor BIND works with RDFlib 6.1.1 and Python 3.10.
BIND - Example:
SELECT ?Column ?PK1
WHERE {
?Column rdf:type dimd:PrimaryKey ;
dimd:isPrimaryKey ?PK1 .
BIND( ?PK1 AS true )
}
EXIST - Example:
SELECT ?Column ?PK1
WHERE {
?Column rdf:type dimd:PrimaryKey .
EXIST ( ?Column rdf:type dimd:PrimaryKey )
}
I always get a ParseException. Does I have to install an additional plugin to get it work?
Many thanks

Related

WikiData SPARQL Query Fails, requires CONTAINS to work

The query below works when I include the line that uses CONTAINS for the filter, but fails if I simply check if the value (LCASE) is equal to "donald trump" (it is).
Use this line, and it works:
FILTER(CONTAINS(LCASE(?idLabel), "donald trump") ).
Use this line, and it fails:
FILTER(LCASE(?idLabel) = "donald trump") .
The output for the query that WORKS has idLabel = "Donald Trump"
SPARQL Query:
SELECT DISTINCT ?id ?idLabel ?PV WHERE {
?id wdt:P106 ?V0. VALUES ?V0 { wd:Q39631 } .
OPTIONAL {
?id rdfs:label ?idLabel .
FILTER(LANG(?idLabel) = 'en') .
} .
# Filter on Label
# WORKS:
FILTER(CONTAINS(LCASE(?idLabel), "donald trump") ).
# DOES NOT WORK
#FILTER(LCASE(?idLabel) = "donald trump") .
# subselect on instance type
{
SELECT ?id WHERE {
?id wdt:P31/wdt:P279* ?PV . VALUES(?PV) {(wd:Q5) } .
}
} .
}
Try it here
My question is WHY the second option does NOT work ?
(And yes, I'm looking for the surgeon Donald Trump, not that other guy)
The labels in Wikidata have language tags, thus, the label literal is
"Donald Trump"#en
and the string after LCASE will be
"donald trump"#en
Indeed CONTAINS works here.
You have to use STR function to get the lexical form, i.e. just
"Donald Trump"
Solution:
FILTER(LCASE(STR(?idLabel)) = "donald trump") .

The DELETE/INSERT operation can be used to remove triples containing blank nodes: how?

I would like to use a SPARQL DELETE/INSERT to ensure that after repeated updates ?performance and certain connected blank nodes do not have multiple property values but only zero (for optional cases) or one (for mandatory cases).
If I send the DELETE/INSERT (see below) to a Jena Fuseki 1.1.1 server I receive this error message: "Blank nodes not allowed in DELETE templates".
However, the specification contains this sentence: "The DELETE/INSERT operation can be used to remove triples containing blank nodes."
So what's a valid form of a DELETE/INSERT that does the job in this case? To ease maintenance it would be good if the DELETE and INSERT parts can remain structurally similar. (This is a follow-up question.)
DELETE {
?performance
mo:performer ?_ ;
mo:singer ?_ ;
mo:performance_of [ ### error marked here ###
dc:title ?_ ;
mo:composed_in [ a mo:Composition ;
mo:composer ?_
]
]
}
INSERT {
?performance
mo:performer ?performer ; # optional
mo:singer ?singer ; # optional
mo:performance_of [
dc:title ?title ; # mandatory
mo:composed_in [ a mo:Composition ;
mo:composer ?composer # optional
]
]
}
WHERE {}
You need something in the WHERE part. This will find the bnodes, put them in variables, and use the DELETE to remove them. The DELETE{} is not itself a pattern to match - the graph pattern is the WHERE {} part.
Something like:
DELETE{
?performance
mo:performance_of ?X .
?X dc:title ?title ;
mo:composed_in ?Y .
?Y a mo:Composition .
?Y mo:composer ?composer .
?performance mo:performer ?performer ;
mo:singer ?singer
}
WHERE {
?performance
mo:performance_of ?X .
?X dc:title ?title ;
mo:composed_in ?Y .
?Y a mo:Composition .
OPTIONAL { ?Y mo:composer ?composer }
OPTIONAL {
?performance mo:performer ?performer ;
mo:singer ?singer
}
}
There is no point making DELETE{} and INSERT{} the same - it's effectively a no-op.
If a variable in bout bound in a particular row from the WHERE{} part, the deletion simply skips that triple, not the rest of the instantiated template.
It may be clearer, to humans, to write the SPARQL Update in several parts. One HTTP request can have several operations, separated by ";":
DELETE{} WHERE {} ;
DELETE{} WHERE {} ;
INSERT DATA{}

SPARQL Query Error with OPTION(TRANSITIVE) on Jena

I have the following Query
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT ?type
WHERE
{
{
SELECT *
WHERE
{
?x rdfs:subClassOf ?type .
}
}
OPTION (TRANSITIVE, t_distinct, t_in (?x), t_out (?type) ) .
FILTER (?x = <http://dbpedia.org/ontology/Hospital>)
}
It works fine when i send it to Virtuoso endpoint but does not work on my Jena instance. In specific i get the following error:
INFO [1] 400 Parse error:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT ?type
WHERE
{
{
SELECT *
WHERE
{
?x rdfs:subClassOf ?type .
}
}
OPTION (TRANSITIVE, t_distinct, t_in (?x), t_out (?type) ) .
FILTER (?x = <http://dbpedia.org/ontology/Hospital>)
}
Lexical error at line 12, column 39. Encountered: " " (32), after : "OPTION" (17 ms)
In case this a Virtuoso specific function, I would appreciate to know an equivalent for this query that would work with *Jena/Standard SPARQL). The expected output should be:
http://dbpedia.org/ontology/Building
http://dbpedia.org/ontology/ArchitecturalStructure
http://dbpedia.org/ontology/Place
http://dbpedia.org/ontology/d0:Location
which represents all superclasses for "Hospital"
This is the expected behavior. This part of the query:
OPTION (TRANSITIVE, t_distinct, t_in (?x), t_out (?type) )
is not standard SPARQL 1.1 but it is a Virtuoso specific extension.
Jena is a SPARQL 1.1 compliant implementation.
The following query does the same thing using standard SPARQL 1.1 syntax, and should work with both Fuseki and Virtuoso (just tested on the dbpedia endpoint and got the same result):
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT ?type
WHERE
{
{
SELECT *
WHERE
{
?x rdfs:subClassOf+ ?type .
}
}
FILTER (?x = <http://dbpedia.org/ontology/Hospital>)
}
The feature used is the "property path".
See http://www.w3.org/TR/sparql11-query/

SPARQL different operator

SPARQL Query
I have some SPARQL query shown below:
SELECT DISTINCT ?name1
WHERE {
GRAPH <blabla>
{
?k swrc:author ?x .
?x foaf:name ?name1 .
} .
GRAPH <blabla2>
{
?l swrc:author ?y .
?y foaf:name ?name2 .
} .
FILTER(?x != ?y) .
}
I want to get the names that exist only in the first graph blabla.
Problem
Counter intuitively I get some names that actually belong to the intersection. This happens because b (of set A) = b (of set B)?
Question
What are exactly the semantics of != ? How can I surpass this problem?
The semantics of != are exactly that its left argument is not equal to its right argument. But a FILTER is evaluated for every possible combination of values - so the query as you formulated it will return all name-values of ?x for which some value of ?y is not equal to it.
If you want to get back only name-values of ?x for which all values of ?y are not equal to it, you should be using a NOT EXISTS clause:
SELECT DISTINCT ?name1
WHERE {
GRAPH <blabla>
{
?k swrc:author ?x.
?x foaf:name ?name1.
}
FILTER NOT EXISTS {
GRAPH <blabla2>
{
?l swrc:author ?x.
}
}
}
Note that using this approach you can actually get rid of variable ?y altogether: you change the condition to just check that author ?x as found in the first graph does not also occur in the second graph.

SPARQL query on Protege for Number of Classes

In order to determine the number of classes in a .owl file,
I was advised to use the following SPARQL query:
SELECT ( count(?class) as ?count )
WHERE { graph <put_your_model_graph_name_here> { ?class a owl:Class . } }
However, when I replace the put_your_model_graph_name_here with my ontology IRI, I get 0
I also tried http://blahblahblah followed immediately by # to no avail.
What am I doing wrong?
Difficult to tell without seeing how you are loading and querying the data. Try using:
SELECT ( count(?class) as ?count ) { ?class a owl:Class }
which will query the default graph, or
SELECT ?g ( count(?class) as ?count )
{ graph ?g { ?class a owl:Class } }
group by ?g
which will give counts for all the named graphs.