Sparql queries with two variables - sparql

How can I make a sparql query with 2 variables?
And let me explain:
I have an ontology for historical maps. My entities are:HistoricalMap , Language , Color
and the object properties that connect them are:hasLanguage , hasColor (the hist.map has language and has color).
If I make the query:
SELECT ?HistoricalMap ?Language ?Color
WHERE { ?HistoricalMap p1:hasLanguage ?Language.
?HistoricalMap p1:hasColor ?Color.
}
I get all the maps that have color and language.
How can i ask for the map that hasColor "Red" AND hasLanguage French?

Because you want "AND", you can just use constants in the pattern.
SELECT ?HistoricalMap
WHERE { ?HistoricalMap p1:hasLanguage "French".
?HistoricalMap p1:hasColor "Red" .
}
If you also want to return the variables still, use FILTER:
SELECT ?HistoricalMap ?Language ?Color
WHERE { ?HistoricalMap p1:hasLanguage ?Language.
?HistoricalMap p1:hasColor ?Color.
FILTER(?Language = "French" && ?Color = "Red")
}

you need to understand how the french language and the colour red are represented in your data.
it should be enough to see how they are returned when doing the query you have mentioned.
querying dbpedia, that would be, for instance:
SELECT ?entity
WHERE {
?entity dbpedia-owl:colour <http://dbpedia.org/resource/Red> .
?entity dbpedia-owl:language <http://dbpedia.org/resource/French_language> .
}

Related

SPARQL: Inverse result on boolean query

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. } }

Exact match of variable string in SPARQL Wikidata Query Service

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.

SPARQL: Insert query results as RDF LIST

I want to get from graph A results bound to a specific variable lets say ?s.
Next I want to insert those results as an RDF list in graph B.
This is my SPARQL Update:
prefix foo:<http://foo.com/>
insert
{
graph <http://B.com>
{
?var foo:propA foo:A ;
foo:propB [ foo:propA foo:A ;
foo:propX ( ?s )
] ;
foo:propC ?o .
}
}
where
{
graph <http://A.com>
{
?s ?p ?o.
BIND(URI(CONCAT("http://example.org/", STRAFTER( STR(?o), "http://someuri.org/"))) as ?var)
}
}
My problem is that it inserts this data:
<http://example.org/varX> foo:propA foo:A ;
foo:propB [ foo:propA foo:A ;
foo:propX ( <http://s1.com> )
],
[
foo:propA foo:A ;
foo:propX ( <http://s2.com> )
] ;
foo:propC <http://oX.com> .
Instead I want it to insert this:
<http://example.org/varX> foo:propA foo:A ;
foo:propB [ foo:propA foo:A ;
foo:propX ( <http://s1.com> <http://s2.com> )
] ;
foo:propC <http://oX.com> .
Can I achieve this result, is it possible?
Basically I want to set the object for the foo:propX predicate, an RDF list containing the elements values bound to variable ?s.
Note: the exact same query executes fine in RDF4J, but strangely causes Blazegraph to throw a
MalformedQueryException: Undefined vocabulary: http://www.w3.org/1999/02/22-rdf-syntax-ns#first
I don't think this is possible using SPARQL only. You'll need to use some of the API functionality to create the RDF collection.
One way to do this is to first construct your graphB as a Model object in memory, and then at the end insert that model in one go. Something along these lines (untested, but this should illustrate the general idea - have a look at the RDF4J documentation and javadoc for more details):
ValueFactory vf = conn.getValueFactory();
TupleQuery query = conn.prepareTupleQuery("SELECT ?s ?o ?var WHERE ...");
List<BindingSet> queryResult = QueryResults.asList(query.evaluate());
// map values of var to values of S
Map<Value, List<Value>> varToS = new HashMap<>();
... // do something clever with the query result to fill this HashMap
// start building our result graph
Model graphB = new TreeModel()
ModelBuilder mb = new ModelBuilder(graphB);
mb.setNamespace("foo", "http://example.org/");
mb.namedGraph("foo:graphB");
for(Value var: varToS.keySet()) {
BNode propBValue = vf.createBNode();
BNode propXValue = vf.createBNode();
mb.subject(var)
.add("foo:propA", "foo:A")
.add("foo:propB", propBValue)
.subject(propBValue)
.add("foo:propA", "foo:A")
.add("foo:propX", propXValue);
// add the values of ?s for the given v as a collection
RDFCollections.asRDF(varToSet.get(var), propXValue, graphB);
}
// insert our created graphB model into the database
conn.add(graphB);

Conditional subquery in SPIN function (SPARQL)

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.

SPARQL DATASET definition

Can anyone explain to me what this statement "Dataset(QuadPattern,μ,GS,GS)" means?Especially, I am trying to figure out the model of DELETE DATA operation (DELETE DATA QuadData) , but I cant understand what Dataset(QuadPattern,{},GS,GS) means.
You seem to be referring to the SPARQL 1.1 Update spec:
Dataset(QuadPattern,μ,DS,GS) ...[an] auxiliary function constructs an RDF Dataset from a QuadPattern, given a solution mapping and an RDF Dataset.
Put simply it's function which takes a bunch of RDF in graphs which may include variables, e.g.:
GRAPH ?g { ?person a Person ; ex:tel ?tel }
{ ?g ex:source ?source }
and a set of solutions μ:
{ ?g => <http://example.com/graph1> , ?person => <http://example.com/alice> , ?tel => "0898 505050" , ?source => <http://192.com/> }
{ ?g => <http://example.com/graph2> , ?person => <http://example.com/bob> , ?tel => "117 117" , ?source => <http://192.com/> }
and binds those values, resulting in a dataset:
{
<http://example.com/graph1> ex:source <http://192.com/> .
<http://example.com/graph2> ex:source <http://192.com/> .
}
GRAPH <http://example.com/graph1> { <http://example.com/alice> a Person ; ex:tel "0898 505050" }
GRAPH <http://example.com/graph2> { <http://example.com/bob> a Person ; ex:tel "117 117" }