I am trying to implement increment/decrement using sparql/sesame query. I came across How to model consecutive numbering without transactions?, which proposes this query:
INSERT {
_:ex a ex:Invoice ;
ex:number ?next .
}
WHERE {
{
SELECT ((MAX(?number) + 1) AS ?next)
WHERE {
{ ?x ex:number ?number ;
a ex:Invoice }
UNION
{ BIND (0 AS ?number) }
}
}
}
I do not understand the purpose of union in the where clause. What is happening in where clause and with the bind? Is the value bound by bind used as a default if there is no triple present for it, meaning that 0 will be the first number?
EDIT:FOLLOW-UP:
Quick clarification....the query in my post (with coalesce) will insert multiple rows (which was the intent of that query). How can I modify that query to just increment/decrement 1 row?? If I add DELETE before insert, then what ld be the behavior? would the ?next be deleted before its selected???/
DELETE {
_:ex a ex:Invoice ;
ex:number ?object .
}
INSERT {
_:ex a ex:Invoice ;
ex:number ?next .
}
WHERE {
{
SELECT ((MAX(?number) + 1) AS ?next)
WHERE {
{ ?x ex:number ?number ;
a ex:Invoice }
UNION
{ BIND (0 AS ?number) }
}
}
}
Can I use query above to just increment 1 row and for the first time insert a row with value 0??
Yes.
What happens is that both arguments of the union provide a solution (the second arg always providing 0), and then the MAX in the projection makes sure that the highest number is chosen. Thus in most cases the second UNION argument does effectively nothing. However, in the case where the first argument does not provide a solution (because no invoice number is present yet), only the second argument will provide a solution and this will be picked as the max and then inserted (+1) as the first number.
Related
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.
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.
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.
I am trying to have SPARQL return 'false' if a set of triples exist in an RDF database. I'm able to return 'true' with an ASK query.
ASK WHERE { ?subjID rdf:type pref:Person. }
As described here, I tried adding NOT EXISTS { } inside of the WHERE, but this results in an error.
ASK WHERE { NOT EXISTS { ?subjID rdf:type pref:Person. } }
The documentation that I linked doesn't describe this but you must put FILTER in front of NOT EXISTS.
ASK WHERE { FILTER NOT EXISTS { ?subjID rdf:type pref:Person. } }
Can anyone help me in sparql. I'm working on ontology based project. I've a structure in protege-owl like
City-hasWeatherConditions-(multiple value i.e temp,dewpoint)
I want to get values against each attribute.
Query:
PREFIX pro: <http://www.semanticweb.org/computer/ontologies/2019/0/fyp.owl#>
select ?indi ?val
where
{
{
select ?indi
where
{
pro:Lahore
<http://www.semanticweb.org/computer/ontologies/2019/0/fyp.owl#hasWeatherCondition>
?indi
}
}
{
select ?val
where
{
<http://www.semanticweb.org/computer/ontologies/2019/0/fyp.owl#DewPoint>
<http://www.semanticweb.org/computer/ontologies/2019/0/fyp.owl#hasDewPoint>
?val
}
}
}
Figure1: Note -- 5.21 is DewPoint value which is repeated in temp.
Figure2:
Exact match of variable string in SPARQL Wikidata Query Service at https://query.wikidata.org does not give the the results I expected.
I was expecting I could do:
SELECT * {
hint:Query hint:optimizer "None" .
{ SELECT DISTINCT (xsd:string(?author_name_) AS ?author_name) { wd:Q5565155 skos:altLabel ?author_name_ . } }
?work wdt:P2093 ?author_name .
}
But I get no returned results from the Wikidata Query Service:
However, if I use the "=" comparison, I can match the strings:
SELECT * {
hint:Query hint:optimizer "None" .
{ SELECT DISTINCT (xsd:string(?author_name_) AS ?author_name) { wd:Q5565155 skos:altLabel ?author_name_ . } }
?work wdt:P50 wd:Q5565155 .
?work wdt:P2093 ?author_name__ .
FILTER (?author_name = ?author_name__)
}
With the current data in Wikidata, I get five rows returned in this query.
Another way to get this data is by using a BIND:
SELECT * {
BIND("Knudsen GM" AS ?author_name)
?work wdt:P2093 ?author_name .
}
I suppose there might be something wrong with the casting as this does not return anything:
SELECT * {
BIND(xsd:string("Knudsen GM") AS ?author_name)
?work wdt:P2093 ?author_name .
}
Combinations with xsd:string changed to STR or no conversion at all in the original query do neither yield result rows.
How do I change the query formula based on whether or not a variable is bound?
I am invoking the magic property like this:
WHERE {
VALUES (?subj) {
([my bound positional parameter value goes here...])
}
?subj :myMagicProperty ?result .
}
Inside the magic property, I do a union:
?result a :Rule .
{
?result :someProp ?subj .
}
UNION
{
FILTER NOT EXISTS {
?result :someProp ?anyValue .
}
}
In other words, get me all results where :someProp is this value or :someProp is not defined.
Here is the tricky part. If ?subj is unbound (i.e., I set it as UNDEF in the VALUES block), the above query goes wild and returns everything.
Instead, I want to check if ?subjis unbound. If ?subj is unbound, :myMagicProperty should only return the following results:
FILTER NOT EXISTS {
?result ?someProp ?anyValue .
}
I have experimented with using FILTER and the BOUND function, but I can't figure out how to get the correct behavior. How can I drop one of UNION clauses from my query when ?subj is not bound?
Updates
Revised the first query to add the VALUES block.
Added missing ?result a :Rule . statement.
Corrected ?someProp to :someProp.
First I'd like to confirm what your intent is. I'd like to do that by asking you to respond to the following query that you can run in TopBraid Composer.
SELECT *
WHERE { GRAPH <http://topbraid.org/examples/kennedys> {
VALUES (?property) {(kennedys:firstName) (kennedys:lastName) (UNDEF)}
{
FILTER(BOUND(?property) )
?s ?property ?result .
}
UNION
{
FILTER(!BOUND(?property))
BIND("not sure what you want to do in this case" AS ?result)
}
}
}
The difference in the code above to your code is that I am setting values of your ?someProp in the VALUES statement, whereas you are setting ?subj.
The UNIONed subgraphs are using BOUND and !BOUND as guards.
Before going further with help I'd like to hear from you with a clearer explanation of the query you are wanting to build. Then I can show you the magic property that will be needed.
It's this piece of your initial post I need to understand more:
Here is the tricky part. If ?subj is unbound (i.e., I set it as UNDEF in the VALUES block), the above query goes wild and returns everything.
Instead, I want to check if ?subj is unbound. If ?subj is unbound, myMagicProperty should only return the following results:
FILTER NOT EXISTS {
?result ?someProp ?anyValue .
}*
With ?someProp undefined, as well as ?result and ?anyValue, what were you expecting to come back? Also this subgraph of yours has no assertions that will populate the graph and therefore will return nothing.
Ralph
The trick is, I need to do the UNION using a variable different than the one passed in as an argument. This way, the UNION operation does not cause the unbound parameter to be bound. After the UNION, I can use a FILTER to control the results based on the input parameter.
SELECT ?result
WHERE {
?result a :Rule .
{
SELECT ?rule ?value ?anyValueMatch
WHERE {
{
?rule :someProp ?value .
BIND (false AS ?anyValueMatch) .
}
UNION
{
FILTER NOT EXISTS {
?rule :someProp ?any .
} .
BIND (true AS ?anyValueMatch) .
} .
}
} .
FILTER ((bound(?subj) && (?value = ?subj)) || (?anyValueMatch = true)) .
}
Another way to do this is with COALESCE:
SELECT ?result
WHERE {
?result a :Rule .
OPTIONAL {
?result :someProp ?value .
}
FILTER (COALESCE(?value = ?subj, !bound(?value)))
}
...this avoids the sub-select and simply filters to include only the ?result matches where '?value = ?subj', and if that clause fails the !bound() clause ensures matches that do not have a :someProp property are also included.