'SPARQL: Conditional INSERT

I'm trying to create a SPARQL statement that inserts some triples only if a certain pattern isn't yet in the graph.

PREFIX ssb: <ssb:ontology:>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

INSERT {
  <ssb:message/some=> rdf:type ssb:Message;
    ssb:seq 7;
    ssb:raw "some text";
    ssb:author 1.
} WHERE {
  FILTER NOT EXISTS {
    [] ssb:seq 7; ssb:author 1
  }
}

Unfortunately, this seems to create the new triples even if a resource with that ssb:seq and ssb:author already exist, tried the with quadstorejs and with oxigraph.

Any suggestion on how to perform such a conditional insert? The goal is that I don't end up with several resources having the same sequence number and author.



Solution 1:[1]

I believe your first attempt is correct and it looks like a bug in the systems that you tried.

The algebra for

  FILTER NOT EXISTS {
    [] ssb:seq 7; ssb:author 1
  }

is the FILTER directly on top of Singleton and it must return a single (empty) solution when the [] ssb:seq 7; ssb:author 1 does not match data. Since there're no variables in your INSERT template, data should be inserted.

The version with OPTIONAL isn't much different, there's an implicit {} before the OPTIONAL, and it's the same Singleton.

I just tried a CONSTRUCT version of your 1st query with Stardog and it worked as expected.

Solution 2:[2]

I found a solution that seems to work:

PREFIX ssb: <ssb:ontology:>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>

INSERT {
  <ssb:message/some=> rdf:type ssb:Message;
    ssb:seq 7;
    ssb:raw "some text";
    ssb:author 1.
} WHERE {
  OPTIONAL {?x ssb:seq 7; ssb:author 1.}
  FILTER (!BOUND(?x))
}

Not sure exactly why, though. I mean the WHERE-Clause either matches nothing because the pattern isn't there or because it is filtered out when it exists.

Sources

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

Source: Stack Overflow

Solution Source
Solution 1 Pavel Klinov
Solution 2 Reto Gmür