SPARQL Update not working - sparql

I am trying to perform a simple update of the value of a property that that has a given resource as its subject.
Here is my query:
WITH <http://127.0.0.1:3000/dendro_graph>
DELETE { <http://127.0.0.1:3000/project/datanotes/records/teste/filho%20do%20teste> <http://purl.org/dc/elements/1.1/creator> ?o0 .
}
INSERT
{
<http://127.0.0.1:3000/project/datanotes/records/teste/filho%20do%20teste> <http://purl.org/dc/elements/1.1/creator> "creator1" .
}
WHERE { <http://127.0.0.1:3000/project/datanotes/records/teste/filho%20do%20teste> <http://purl.org/dc/elements/1.1/creator> ?o0 .
}
The result of this is that the delete is executed, but the insert is not; I end up destroying all instances of the property, but no new value is added.
If I remove the WHERE clause, I end up with duplicate triples, because it seems the DELETE is not executed.
What am I doing wrong?
EDIT:
This code produces the duplicates:
WITH <http://127.0.0.1:3000/dendro_graph>
DELETE
{
<http://127.0.0.1:3000/project/datanotes/records/teste/filho%20do%20teste> <http://purl.org/dc/elements/1.1/creator> ?o0 .
}
INSERT
{
<http://127.0.0.1:3000/project/datanotes/records/teste/filho%20do%20teste> <http://purl.org/dc/elements/1.1/creator> "creator1" .
}

The query without the WHERE clause is not a legal SPARQL expression, and should have resulted in a syntax error. If the engine you're using accepts this, then that is a bug in that engine.
At first glance, ditto for the earlier operation, which you say deletes but does not insert: as far as I can see the SPARQL expression is correct, and if as you say the insert part does not get executed, that means you've discovered a bug in the engine that executes it. I recommend you get in touch with the developers directly.

Here is a workaround I used to get this working (finally thank God). It seems you can specify several operations to be executed over the graph in a single operation using the semicolon ;.
I ended up specifying the DELETE statement and then the UPDATE one
Check this out for code sample : SPARQL Update example for updating more than one triple in a single query

Related

RDFlib Blank node update query

I am trying to update the object of a triple with a blank node as its subject using RDFlib. I firstly select the blank node in the first function and insert this blank node into the update query in the second function, however, this doesn't provide me with the required output. I can't use the add() method or initBindings as I need to save the SPARQL query executed for the user.
Sample data
#prefix rr: <http://www.w3.org/ns/r2rml#> .
[ rr:objectMap [ rr:column "age" ;
rr:language "dhhdhd"] ].
Code
mapping_graph = Graph().parse("valid_mapping.ttl",format="ttl")
# find the blank node for the update query
def find_om_IRI():
query = """SELECT ?om
WHERE {
?om rr:language 'dhhdhd' .
}
"""
qres = mapping_graph.query(query)
for row in qres:
return row[0]
# insert blank node as subject to update query
def change_language_tag():
om_IRI = find_om_IRI()
update_query = """
PREFIX rr: <http://www.w3.org/ns/r2rml#>
DELETE DATA{
_:%s rr:language 'dhhdhd' .
}
""" % (om_IRI)
processUpdate(mapping_graph, update_query)
print(update_query)
print(mapping_graph.serialize(format="ttl").decode("utf-8"))
return update_query
change_language_tag()
This however returns the following output. Leaving the graph unchanged.
#prefix rr: <http://www.w3.org/ns/r2rml#> .
[ rr:objectMap [ rr:column "age" ;
rr:language "dhhdhd"] ].
If you filter based on the blank node value. This is the final query I came up with.
PREFIX rr: <http://www.w3.org/ns/r2rml#>
DELETE { ?om rr:language "dhhdhd" }
INSERT { ?om rr:language "en-fhfhfh" }
WHERE {
SELECT ?om
WHERE {
?om rr:language "dhhdhd" .
FILTER(str(?om) = "ub1bL24C24").
}
}
Indeed, as commenter #TallTed says "Blank nodes cannot be directly referenced in separate queries". You are trying to do something with BNs for which the are expressly not defined, that is persist their absolute identity, e.g. across separate queries. You should take the approach of relative identification (locate the BN with reference to identified, URI, nodes) or single SPARQL queries. So this question is an RDF/SPARQL question, not an RDFlib question.
You said: "I can't combine the queries as there could be other object maps with the same language tag". So if you cannot deterministically refer to a node due to its lack of distinctness, you will have to change your data, but I suspect you can - see the suggestion at the end.
Then you said "I have figured out the solution and have updated the question accordingly. Its a hack really..." Yes, don't do this! You should have a solution that's not dependent on some quirks of RDFlib! RDF and Semantic Web in general is all about universally defined and standard data and querying, so don't rely on a particular toolkit for a data question like this. Use RDFlib only as an implementation but one that should be replicable in another language. I personally model all my RDFlib triple adding/deleting/selecting code as standard SPARQL queries first so that my RDFlib code is then just a standard function equivalent.
In your own answer you said "If you filter based on the blank node value...", also don't do this either!
My suggestion is to change your underlying data to include representations of things - named nodes etc - that you can use to fix on for querying. If you cannot distinguish between things that you want to change without resorting to hacks, then you have a data modelling problem that needs solving. I do think you can distinguishes object maps though.
In your data, you must be able to fix on the particular object map for which you are changing the language. Is the object map unique per column and is the column uniquely identified by its rr:column value? If so:
SELECT ?lang
WHERE {
  ?om rr:column ?col .  ?om rr:language ?lang .
  FILTER (?col = "age")
}
This will get you the object map for the column "age" so, to change it:
DELETE {
  ?om rr:language ?lang .
}
INSERT {
  ?om rr:language "new-language" .
}
WHERE {
  ?om rr:column ?col .  ?om rr:language ?lang .
  FILTER (?col = "age")
}

sparql expecting one of "where", "using"

I am trying to do a simple insert query in the web interface of Fuseki server. I have set the endpoint to /update (instead of the default /sparql).
I have the following query from https://www.w3.org/Submission/SPARQL-Update/:
PREFIX dc: <http://purl.org/dc/elements/1.1/>
INSERT { <http://example/egbook3> dc:title "This is an example title" }
This query gets translated to:
http://localhost:3033/dataset.html#query=PREFIX+dc%3A+%3Chttp%3A%2F%2Fpurl.org%2Fdc%2Felements%2F1.1%2F%3E%0AINSERT+%7B+%3Chttp%3A%2F%2Fexample%2Fegbook3%3E+dc%3Atitle++%22This+is+an+example+title%22+%7D%0A
or
curl http://localhost:3033/infUpdate/update -X POST --data 'update=PREFIX+dc%3A+%3Chttp%3A%2F%2Fpurl.org%2Fdc%2Felements%2F1.1%2F%3E%0AINSERT+%7B+%3Chttp%3A%2F%2Fexample%2Fegbook3%3E+dc%3Atitle++%22This+is+an+example+title%22+%7D%0A' -H 'Accept: text/plain,*/*;q=0.9' as visible using the Share your query button.
The query returns the following error:
Error 400: Encountered "<EOF>" at line 2, column 73.
Was expecting one of:
"where" ...
"using" ...
Fuseki - version 2.4.0 (Build date: 2016-05-10T11:59:39+0000)
The error occurs both in the web interface and with curl. What could be the problem here? SELECT queries work without problems. Loading triples from a file through the web interface upload form also works. Additional question: the normal post request uses query= and the curl version uses update=, why is this different?
The document you're referencing is the 2008 SPARQL Update submission, not the actual 2013 SPARQL 1.1 recommendation. The recommendation is the actual standard, the submission is not.
An update (insert or delete) isn't a query (select, ask, construct), and the syntax for the two kinds of query aren't necessarily the same. You note (correctly) that WHERE is optional in a select query, but that doesn't mean that it's optional in an insert. There are two forms of insert. There's INSERT DATA which has the syntax:
INSERT DATA QuadData
and there's DELETE/INSERT which has the syntax:
( WITH IRIref )?
( ( DeleteClause InsertClause? ) | InsertClause )
( USING ( NAMED )? IRIref )*
WHERE GroupGraphPattern
DeleteClause ::= DELETE QuadPattern
InsertClause ::= INSERT QuadPattern
So if you're using INSERT { … }, then that's the InsertClause of a DELETE/INSERT form, and you need to follow it with WHERE …. Since you're using static data, you should probably just use the INSERT DATA form:
PREFIX dc: <http://purl.org/dc/elements/1.1/>
INSERT DATA { <http://example/egbook3> dc:title "This is an example title" }

how to exclude one instance from SPARQL query result

I have a query to get some similar instances for a specific instance, which is owbes:Dies_Irae instance. This is the query:
CONSTRUCT { ?recommendable0 ?predicate0 ?similarity0 } WHERE {
?recommendable0 ?predicate0 ?object0.
owbes:Dies_Irae ?predicate0 ?object0.
?predicate0 owbes:hasSimilarityValue ?similarity0.
?recommendable0 rdf:type ?someType.
?someType rdfs:subClassOf owbes:Recommendable.
}
It works fine, I get in the results what I'm supposed to. However, I also get the same instance owbes:Dies_Irae. Is there a way to exclude it from the result?
Well, I'm sure there is. I tried to search, I found that there is a filter, I tried to use it, but no succeed. This is the filter that I apply FILTER (?recmmendable0 != owbes:Dies_Irae)
I also tried to check if both of them have the same rdf:about but it didn't work.
Here you go the result:
<http://www.welovethesemanticweb.com/recommendation-systems#Requiem:_Sequentia>
recommendation-systems:hasArtist
"0.4"^^xsd:double .
recommendation-systems:Le_nozze_di_Figaro
recommendation-systems:hasArtist
"0.4"^^xsd:double .
recommendation-systems:Dies_Irae
recommendation-systems:hasArtist
"0.4"^^xsd:double .
as you see, the last instance is the one that I'd like to exclude
FILTER (?recmmendable0 != owbes:Dies_Irae)
You didn't spell recommendable0 correctly in your filter. Since the variable isn't used anywhere else, it never has a value, so the filter doesn't have anything to compare.

DBpedia get all cities in the world - missing a few

I use this sparql query to get as much cities as possible:
select * where {
?city rdf:type dbo:PopulatedPlace
}
However, some expected ones are missing e.g.
http://dbpedia.org/resource/Heidelberg
(neither that nor one of its wikiRedirects)
which is of a dbo:PopulatedPlace as this query returns true (in JSON):
ask {
:Heidelberg a dbo:PopulatedPlace
}
I need that list to be exhaustiv because later I will add constraints based on user input.
I use http://dbpedia.org/snorql/ to test the queries.
Any help is appreciated.
UPDATE:
One of the Devs told me the public endpoint is limited ( about 1K ).
I'll come up with a paginated solution and see if it contains the 'outlier'.
UPDATE2:
The outlier is definitly in the resultset of rdf:type dbo:Town.
Using dbo:PopulatedPlace yields too many results to check per hand, though.
The public endpoint limits results to about 1K. Pagination or use of a smaller subclass of dbo:PopulatedPlace yields the result.

SPARQL-Query results invalid?

I run a Virtuoso Server and missed a number of results when making a SPARQL-Select request. I tracked it down and find a really strange behaviour, that I cannot explain.
But to start from the beginning.
The endpoint I query can be found at http://creativeartefact.org/sparql
I) Check for a specific triple:
ASK WHERE {
<http://creativeartefact.org/mbrainzImport/f18e677a-4051-486a-aa64-d9a3bfef90af>
<http://creativeartefact.org/ontology/represents>
<http://creativeartefact.org/mbrainzImport/35ed9f2a-6ce4-44ca-9c7a-967377b0e007>. }
The query returns TRUE
II) Now getting a bit more unspecific:
ASK WHERE {
?s
<http://creativeartefact.org/ontology/represents>
<http://creativeartefact.org/mbrainzImport/35ed9f2a-6ce4-44ca-9c7a-967377b0e007>. }
If the first returns true, the second shall do as well, shouldn't it? But it doesn't. It return FALSE!
If I replace the predicate or the object with a variable, it returns true as expected. Only when setting a variable for the subject, it returns false.
That the data really exists in the triple store can be tested by running the query
SELECT * WHERE {
?s
?p
<http://creativeartefact.org/mbrainzImport/35ed9f2a-6ce4-44ca-9c7a-967377b0e007>. }
You will see, that both results comw with p = http://creativeartefact.org/ontology/represents - which is exactly the predicate I am asking for in the former query.
To make it even more strange, there ARE triples with the aforementioned format, that return the triples:
select * {
?s
<http://creativeartefact.org/ontology/represents>
<http://creativeartefact.org/mbrainzImport/e4003568-5645-4ee1-abd0-2e8156272e59>. }
Any idea, what is happening here?
Thanks in advance,
Frank
The Virtuoso being used is an original 07.00.3203 build from 2013.
I would suggest upgrading to the latest Virtuoso 07.10.3211, open source or commercial, depending on which is in use here, and see if the problem persists ...