'SPARQL Update (DELETE/INSERT) with WHERE Condition Referencing Multiple Graphs

I'm trying to do a SPARQL update in Jena Fuseki, but I can't seem to get it to work.

The following is the issue:

I have triples in a graph (named freetest), and those triples need to be changed.
And in a separate graph (named knora-base), I have a "ontology" describing the data in the first graph.

In order to identify the triples that need updating, I need information from the ontology.

In a SELECT query, this works perfectly fine:

SELECT *
FROM <http://www.knora.org/data/0001/freetest>
FROM <http://www.knora.org/ontology/knora-base>
WHERE {
    ?s ?p ?o.
    ?s <http://www.knora.org/ontology/knora-base#hasPermissions> 'b' .
    ?def <http://www.w3.org/2000/01/rdf-schema#subClassOf>* <http://www.knora.org/ontology/knora-base#Value> .
    ?s a ?def
}
LIMIT 25

The two FROM clauses make the WHERE block act on a union of the two graphs, so that I can check if hasPermission equals 'b', which is a triple in the data graph (freetest), as well as that the resource at hand is of type ?def (again in the data graph), which must be a <subClassOf>* of Value (which is defined in the ontology graph).

As mentioned, this works as expected.

However I don't get it to work to update those triples. Among many variations, I tried:

DELETE { GRAPH <http://www.knora.org/data/0001/freetest> 
    {?s <http://www.knora.org/ontology/knora-base#hasPermissions> ?perm}
}
INSERT { GRAPH <http://www.knora.org/data/0001/freetest> 
    {?s <http://www.knora.org/ontology/knora-base#hasPermissions> ?new}
}
USING <http://www.knora.org/ontology/knora-base>
USING <http://www.knora.org/data/0001/freetest>
WHERE {
    VALUES ?perm {'b'}
    VALUES ?new {'c'}
    ?s <http://www.knora.org/ontology/knora-base#hasPermissions> ?perm .    
    ?def <http://www.w3.org/2000/01/rdf-schema#subClassOf>* <http://www.knora.org/ontology/knora-base#Resource> .
    ?s a ?def
}

I expected this to have the same behaviour as the SELECT query above, with multiple USING statements giving me access to multiple graphs in the WHERE clause.

However this doesn't update any triples in the database.

Note though, that when I remove the line ?def <http://www.w3.org/2000/01/rdf-schema#subClassOf>* <http://www.knora.org/ontology/knora-base#Resource> . it does update the triples. But obviously without the restriction I wanted, so too many triples get updated.

I'm sure I'm just not fully understanding named graphs, sparql update, USING, or all of them. But I also can't find much information on the topic. (While named graphs in SELECT seem to be covered by quite a number of very informative articles.)


Update 1:

According to the comments, I also tried to explicitly define the graph in the WHERE clause:

WITH <http://www.knora.org/data/0001/freetest>
DELETE { GRAPH <http://www.knora.org/data/0001/freetest> 
    {?s <http://www.knora.org/ontology/knora-base#hasPermissions> ?perm}
}
INSERT { GRAPH <http://www.knora.org/data/0001/freetest> 
    {?s <http://www.knora.org/ontology/knora-base#hasPermissions> ?new}
}
WHERE {
    VALUES ?perm {'c'}
    VALUES ?new {'d'}
    ?s <http://www.knora.org/ontology/knora-base#hasPermissions> ?perm .
    GRAPH <http://www.knora.org/ontology/knora-base> {
        ?def <http://www.w3.org/2000/01/rdf-schema#subClassOf>* <http://www.knora.org/ontology/knora-base#Resource> .
    }
    ?s a ?def
}

This did not change the observed behaviour.


Update 2:

I tried to reproduce it with a simple sample, so I did the following:

  1. Use my regular Fuseki Setup
  2. Send a DROP ALL to have the same settings but no triples
  3. Upload a simple dataset:
@prefix a: <http://test.org/a#> .
@prefix b: <http://test.org/b#> .
@prefix rdf:  <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#> .
@prefix xsd:  <http://www.w3.org/2001/XMLSchema#> .
@prefix owl:         <http://www.w3.org/2002/07/owl#> .

a:A {
    a:Resource 
        a owl:Class ;
        rdfs:label "Resource"@en .

    a:Value 
        a owl:Class ;
        rdfs:label "Value"@en .

    a:SubResource 
        a owl:Class ;
        rdfs:subClassOf a:Resource ;
        rdfs:label "Sub-Resource"@en .
}

b:B {
    b:ResourceInstance 
        a a:Resource ;
        b:hasValue "a".

    b:ValueInstance 
        a a:Value ;
        b:hasValue "a".

    b:SubResourceInstance 
        a a:SubResource ;
        b:hasValue "a".
}

In this, a: is the ontology and b: is the data.

Then I sent the following update:

WITH <http://test.org/b#B>
DELETE { 
    ?s <http://test.org/b#hasValue> ?oldVal
}
INSERT {
    ?s <http://test.org/b#hasValue> ?newVal
}
USING <http://test.org/a#A>
USING <http://test.org/b#B>
WHERE {
    VALUES ?oldVal {'a'}
    VALUES ?newVal {'b'}
    ?s <http://test.org/b#hasValue> ?oldVal .
    ?def <http://www.w3.org/2000/01/rdf-schema#subClassOf>* <http://test.org/a#Resource> .
    ?s a ?def
}

This produced the expected result: The values in b:ResourceInstance and b:SubResourceInstance get updated, but not in b:ValueInstance.

So, to conclude: SPARQL and Fuseki do exactly what they should... so the initial problem seems to have to do with my real data (or my lack of understanding of my data).



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source