Fuseki update does not appear to be working in version 4.6.1 - sparql

I'm looking to incorporate Fuseki into a project where I need to update a graph, but so far I have not been able to get it to work. To demonstrate this issue, I created a dataset using example 5 from the W3 SPARQL 1.1 standard document.
The dataset w3_update_example_5.ttl (from the standard):
# Graph: http://example/addresses
#prefix foaf: <http://xmlns.com/foaf/0.1/> .
<http://example/president25> foaf:givenName "Bill" .
<http://example/president25> foaf:familyName "McKinley" .
<http://example/president27> foaf:givenName "Bill" .
<http://example/president27> foaf:familyName "Taft" .
<http://example/president42> foaf:givenName "Bill" .
<http://example/president42> foaf:familyName "Clinton" .
The update request, w3_update_example_5.rq (from the standard):
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
WITH <http://example/addresses>
DELETE { ?person foaf:givenName 'Bill' }
INSERT { ?person foaf:givenName 'William' }
WHERE
{ ?person foaf:givenName 'Bill'
}
I start Fuseki with the following command line:
$ ../tmp/apache-jena-fuseki-4.6.1/fuseki-server --update --verbose --file w3_update_example_5.ttl --localhost /w3_update_example_5
I submit this request via s-update:
$ s-update --service=http://localhost:3030/w3_update_example_5/update --update=w3_update_example_5.rq
The server appears to receive the request correctly, but the it returns a 204 No Content status and does not update the graph. The verbose logs from the server for this request:
09:56:32 INFO Fuseki :: [2] POST http://localhost:3030/w3_update_example_5/update
09:56:32 INFO Fuseki :: [2] => User-Agent: SOH/Fuseki 1.0.0
09:56:32 INFO Fuseki :: [2] => Host: localhost:3030
09:56:32 INFO Fuseki :: [2] => Content-Length: 205
09:56:32 INFO Fuseki :: [2] => Content-Type: application/sparql-update
09:56:32 INFO Fuseki :: [2] Update = PREFIX foaf: <http://xmlns.com/foaf/0.1/> WITH <http://example/addresses> DELETE { ?person foaf:givenName 'Bill' } INSERT { ?person foaf:givenName 'William' } WHERE { ?person foaf:givenName 'Bill' }
09:56:32 INFO Fuseki :: [2] 204 No Content (23 ms)
After this request, the Fuseki web UI shows the graph has not changed.
I can edit the graph using the web UI, but when I look at the network traffic, it seems to just send the entire graph back to the server. I don't want to do this. I need to be able to manipulate individual triples in the graph.
Jena has been around long enough that I would expect this to "just work". What am I doing wrong or is this a problem with the server?
I have not had any issues with submitting queries to the server, assuming I have the query correct.

Thanks to AndyS for guidance. Once I removed the WITH line, it worked!
The corrected query:
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
DELETE { ?person foaf:givenName 'Bill' }
INSERT { ?person foaf:givenName 'William' }
WHERE
{ ?person foaf:givenName 'Bill'
}

Related

Apply literal type to object in INSERT query

In a certain knowledge graph there is a large number of individuals that need
to be assigned a literal token of the type xsd:token. It is not practical to
do so manually, therefore I am trying with an INSERT instruction. However, I
can't find a way to assign the desired literal type in that kind of query.
Consider in first place this basic example knowledge graph:
#prefix : <http://my.example.web/> .
#prefix foaf: <http://xmlns.com/foaf/0.1/> .
:1 a foaf:Person ;
foaf:name "Jane Doe" .
:2 a foaf:Person ;
foaf:name "John Smith" .
The exercise would be to add a token created by removing the blank spaces from
the foaf:name literal. For the :1 this would translate into the addition of the triple:
:1 dcterms:identifier "JaneDoe"^^xsd:token .
With a SELECT query I can archive it the following
way:
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT STRDT(?token, xsd:token)
WHERE {
GRAPH <http://my.example.web/> {
?s foaf:name ?name .
BIND(REPLACE(STR(?name)," ","") AS ?token) .
}
}
Which produces the result:
LONG VARCHAR
_______________________________________________________________________________
JaneDoe
JohnSmith
2 Rows. -- 54 msec.
Now using the same formulation, but with an INSERT query:
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX dcterms: <http://purl.org/dc/terms/>
INSERT
{
GRAPH <http://my.example.web/> {
?s dcterms:identifier STRDT(?token, xsd:token) .
}
}
WHERE {
GRAPH <http://my.example.web/> {
?s foaf:name ?name .
BIND(REPLACE(STR(?name)," ","") AS ?token) .
}
}
An error is the result:
*** Error 37000: [Virtuoso Driver][Virtuoso Server]SQ074: Line 17 (line 17 of "(console)"): SP030: SPARQL compiler, line 9: syntax error at 'STRDT' before '('
In essence I need a way to apply the STRDT function to the
object of a triple inside the INSERT clause. Or any other alternative mechanism allowing to set a literal type in this kind of query.
Both your queries are invalid:
SELECT STRDT(?token, xsd:token)
According to the SelectClause production, an expression must be followed by AS to give it a variable binding. In essence, you have to use the same syntax you would have used after BIND (you also need parentheses around it). As for why Virtuoso accepts this, well Virtuoso does not strictly follow all of SPARQL ‒ it also allows , between the variables in SELECT, has the DEFINE clause, and allows undeclared prefixes if they are recognized by the store.
This is valid:
SELECT (STRDT(?token, xsd:token) AS ?tokenTyped)
or modify the BIND:
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?token
WHERE {
GRAPH <http://my.example.web/> {
?s foaf:name ?name .
BIND(STRDT(REPLACE(STR(?name)," ",""), xsd:token) AS ?token) .
}
}
This seems the cleanest to me.
Likewise, for the second query, you cannot have an expression as an object of a triple (or any position for that matter), see the Object production. Using a variable is the best the syntax allows you to do (while it would certainly be nice to be able to use expressions as you wanted):
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX dcterms: <http://purl.org/dc/terms/>
INSERT
{
GRAPH <http://my.example.web/> {
?s dcterms:identifier ?token .
}
}
WHERE {
GRAPH <http://my.example.web/> {
?s foaf:name ?name .
BIND(STRDT(REPLACE(STR(?name)," ",""), xsd:token) AS ?token) .
}
}
I have tested it and it should work on OpenLink Virtuoso version 07.20.3231. If you have issues with this, perhaps the Virtuoso instance needs to be updated, or refer to GitHub.

SPARQL query with Apache Jena Fuseki on local database importing geonames

I want to retrieve the name of the city associated to a person in a triplestore which links a person to a geonames entry. I am using a local server (Apache Jena Fuseki) on this minimal triplestore (in turtle):
#prefix ex: <http://www.example.audio/ex> .
#prefix foaf: <http://xmlns.com/foaf/0.1/> .
#prefix gn: <http://www.geonames.org/ontology#> .
ex:Cristina rdf:type foaf:Person ;
foaf:firstName "Cristina" ;
foaf:based_near <https://sws.geonames.org/3164527/> .
https://sws.geonames.org/3164527/ is the URI of the city of Verona
This is the query I am trying to perform:
SELECT ?person
WHERE {
?person foaf:based_near ?city .
?city gn:name "Verona" .
}
As you can see, what I wish to do is using the gn:name predicate.
How can I achieve this? Obviously I am doing something wrong.

getting labels from Wikidata in graphDB

I have a list of artstyles in graphDB, i am trying to use the SERVICE function to get their labels from Wikidata with this query:
PREFIX gp: <http://www.semanticweb.org/kandd/group76/final_project#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT ?movement ?label
WHERE{
?artist gp:hasArtStyle ?movement.
SERVICE <https://query.wikidata.org/sparql>{
?movement rdfs:label ?label .
FILTER (langMatches( lang(?label), "EN" ) )
}
}
note that gp is a namespace that only exists in my graph, not anywhere on the internet and also note that ?movement contains a list of valid Wikidata URIs such as http://www.wikidata.org/entity/Q186030
yet still the response I get is:
Error 500: error
Query evaluation error: org.eclipse.rdf4j.query.QueryEvaluationException: org.eclipse.rdf4j.query.QueryEvaluationException: java.io.IOException: Unkown record type: 83 (HTTP status 500)
What am I doing wrong?
Remember that you query is handled from the inside to the outside, meaning that the service part is handled first, and then the part where you use your own specific property.
Currently, your query on WikiData is very general. You ask for everything that has a rdfs:label, and then filter on all the English labels it returns.
Given this, my guess is that you query simply times out. Instead, I would try something like this:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX wdt: <http://www.wikidata.org/prop/direct/>
PREFIX wd: <http://www.wikidata.org/entity/>
SELECT *
WHERE{
SERVICE <https://query.wikidata.org/sparql>{
?artist wdt:P101 wd:Q186030 ; #Field of Work is contemporary art
wdt:P31 wd:Q5 ; #instance of Human
rdfs:label ?name . #get the label
FILTER (langmatches(lang(?name), "en"))
}
}
If I try this in GraphDB, it returns 156 results.

How to pass a variable to a SERVICE expression in SPARQL?

I have built an ontology for live concerts, Concert_Ontology.ttl. This contains definitions for concerts, artists, repertoires, and songs. I want to match the artists in my ontology and the artists in the dbpedia Person ontology based on the attributes c:artistName and dbp:name. I have written the following query to access the dbpedia endpoint and retrieve additional information about the artists.
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX dbo: <http://dbpedia.org/ontology/>
PREFIX dbp: <http://dbpedia.org/property/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX c: <http://localhost:8080/Concert_Ontology.ttl#>
SELECT ?performer ?artistname ?dob
WHERE {
?performer a c:Artist ;
c:artistName ?artistname .
SERVICE <http://dbpedia.org/sparql> {
?person a dbo:Person ;
dbo:birthDate ?dob ;
dbp:name ?n .
FILTER (str(?n) = ?artistname)
}
}
However, I do not seem to be able to access the ?artistname variable from within the SERVICE expression. If I put the FILTER method outside the SERVICE expression the query works, but since dbpedia has a return cap of 10000 results, I am not able to retrieve and match all the artists.
Could someone guide me in finding a solution to this problem?
I found a solution to my problem. The filter function will not work with a local variable on the remote endpoint. However, if I omit the filter function and simply use the same variable name for the local and remote variable, it will return the correct results. Like this:
SELECT ?performer ?artistname ?dob
WHERE {
?performer a :Performer ;
:artistName ?artistname .
SERVICE <http://dbpedia.org/sparql> {
?person a dbo:Person ;
dbo:birthDate ?dob ;
dbp:name ?artistname .
}
}
SERVICE executes the pattern at the server. The server does not know the value of ?artistname (of which there can be many and is local information to the caller). So the best that can happen is to execute the
?person a dbo:Person ;
dbo:birthDate ?dob ;
dbp:name ?n .
and filter locally.
You can pass variable as IRI to SERVICE.
bind(iri(concat("http://dbpedia.org/resource/",replace(? artistname," ","_"))) as ?person)
and no need to filter by name.

Stardog rule doesn't trigger

I'm having trouble writing a correct Stardog rule. As I haven't found a way to validate the syntax of the rule, I don't now if it's a syntax or a logical error. Eitherway, the rule doesn't seem to be triggered when reasoning is enabled (reasoning=SL in version 2, reasoning=true in version 3).
#prefix : <http://www.example.org/rules#> .
#prefix rule: <tag:stardog:api:rule:> .
#base <http://www.example.org/rules#> .
[] a rule:SPARQLRule ;
rule:content """
PREFIX : <http://www.example.org/rules#>
PREFIX draft: <http://our/prefix#>
IF {
?x a draft:Obs; draft:has_code ?code .
?z a <http://www.w3.org/ns/sparql#UUID> . // OR: BIND (UUID() AS ?z)
}
THEN {
?z a draft:Code .
?x draft:has_code ?z .
}
""" .
I'm trying to trigger the rule with the following SPARQL query:
PREFIX : <http://our/prefix>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT ?code
FROM <tag:stardog:api:context:default>
FROM <http://our/graph>
WHERE {
?s rdf:type :Obs .
?obs :has_code ?code .
}
This is likely due to the cyclic nature of the rule. You're inferring :has_code which will in turn be used to fire the rule again, and again, and so forth.
This is a bit easier to visualize when you consider how rules with more than one atom in the header a broken up.