SPARQL: Understanding what value gets assigned to variable - sparql

Hi I am new to SPARQL and I would like to understand better some things regarding variable assigments. Lets say I have the below:
SELECT ?z WHERE
{
?x n:type 'Type_1' .
?x n:belongs ?r .
?r n:belongs ?z .
?y n:type 'Type_1' .
?y n:belongs ?r_2 .
?r_2 n:belongs ?z . FILTER(?x != ?y)
}
In the above example query ?r and ?r_2 from my understanding have different values stored inside .Does the same applies for both variables ?z, or because both have the same name also have the same value stored inside?. An explanation would be appreciated. Cheers!

You can think of SPARQL as a template. It is a declarative language where you explicitly put in the things you know, and you put in variables for the things you don't.
The query executes, and puts the values of the things you don't yet know, into the response, against the variable names.
A variable called 'x' is the same variable throughout the query. It's response value is 'bound' to the parameter 'x'.
There is a SPARQL tutorial which I wrote in the open source graph-notebook project found here: https://github.com/aws/graph-notebook
After you run the notebook, navigate to 06-LANGUAGE-TUTORIALS
Although it was originally built for Amazon Neptune, it is open source and will work with any SPARQL 1.1 endpoint.

Related

Sparql query to read from all named graphs without knowing the names

I am looking to run a SPARQL query over any dataset. We dont know the names of the named graphs in the datasets.
These are lots of documentation and examples of selection from named graphs when you know the name of the named graph/s. There are examples showing listing named graphs.
We are running the Jena from Java so it would be possible to run 2 queries, the first gets the named graphs and we inject these into the 2nd.
But surely you can write a single query that reads from all named graphs when you dont know their names?
Note: we are looking to stay away from using default graph/s as their behaviour seems implementation dependent.
Example:
{
?s foaf:name ?name ;
vCard:nickname ?nickName .
}
If you want the pattern to match within one graph and wish to try each graph, use the GRAPH ?g form.
GRAPH ?g
{ ?s foaf:name ?name ;
vc:nickname ?nickName .
}
If you want to make a query where the pattern matches across named graphs, -- e.g. foaf:name in one graph and vCard:nickname in another, same subject --
then set union default graph tdb2:unionDefaultGraph true then the default graph as seen by the query is the union (actually, RDF merge - no duplicates) of all the named graphs. Use the pattern as originally given.
Fuseki configuration file extract:
:dataset_tdb2 rdf:type tdb2:DatasetTDB2 ;
tdb2:location "DB2" ;
## Optional - with union default for query and update WHERE matching.
tdb2:unionDefaultGraph true ;
.
In code, not Fuseki, the application can use Dataset.getUnionModel().

DBPedia SPARQL, return certain number of relevant page URIs for entity EXCEPT the URIs where the entity belongs to a set of subclasses of Owl:Thing

Looking for SPARQL query to do the following:
For example, I have the word Apple. Apple may refer to the organization Apple_Inc or the Species of Plants class as per the ontology. Owl: Thing has a subclass called Species, so I want to return those most relevant/maximum-hit URIs where the keyword Apple does not belong to the Species subclass. So when you return all the URIs, http://dbpedia.org/page/Apple should not be one of them, neither must ANY relevant link that comes under Species subclass.
By maximum-hit/most relevant I mean the top returned results that match the query! Like when you access the PrefixSearch (i.e. Autocomplete) API, it has the parameter called MaxHits.
For example http://lookup.dbpedia.org/api/search/PrefixSearch?QueryClass=&MaxHits=2&QueryString=berl is a link where you want to return the top 2 URIs that match the QueryString=berl.
Like I'm actually really struggling to even explain the work I've done so far because I'm not able to understand the structure and how to formulate a proper query..
with respect to negation in SPARQL, I found a relevant portion of the documentation in the link here.. But I do not know how and where to proceed from there, and cannot understand why keywords like ?person are used.. I can understand the person is used to selected well.. PEOPLE names, but I would like to know how and where to find these keywords like ?person, ?name to represent a specific entity..
SELECT ?uri ?label
WHERE {
?uri rdfs:label ?label .
filter(?label="car"#en)
}
I would really appreciate if someone could link me the part of the documentation I can clearly read and understand that ?uri is used to select a URI in the form www.dbpedia.org'/page/SomeEntity and what these ?person, ?name, ?label represent.
I'm actually so lost.. I will go up and start eating one elephant at a time. For now, I'll be very grateful if I get an answer to this.
If there is anyway you know where I can avoid learning and using SPARQL, that would work too! I know Python well enough, so leveraging an API to pull this information is also fine by me. This question was posted by me.
Answer posted by #Stanislav-Kravin --
SELECT DISTINCT ?s
WHERE
{ ?s a owl:Thing .
?s rdfs:label ?label .
FILTER ( LANGMATCHES ( LANG ( ?label ), 'en' ) )
?label bif:contains '"apple"' .
FILTER NOT EXISTS { ?s rdf:type/rdfs:subClassOf* dbo:Species }
}

Querying DBpedia-Live with SPARQL does not give same answer as DBpedia

I want to query DBpedia with DBpedia Live endpoint.
I have this query :
SELECT *
WHERE {
?x a dbo:Person .
?x rdfs:label "Usain Bolt"#en .
}
This query gives the correct answer with most names I tried (for example “Teddy Riner"#en) but it fails with Usain Bolt and Rachid Badouri.
I don’t get why as their DBpedia pages (Teddy Riner, Usain Bolt) are constructed the same way: they both have a rdfs:label, which is written exactly like I did.
It seems to me that there is an incoherence between the endpoint and DBpedia. But I don’t think that it's because the endpoint is not to date.
Even more surprising, this query gives the correct answer:
SELECT *
WHERE {
?x rdfs:label "Usain Bolt"#en .
}
However, Usain Bolt is a dbo:Person! Same thing for Rachid Badouri.
Could someone explain me why the first query does not give answer?
Any help would be appreciated! Thanks
According to DBpedia-Live, at the time of writing, the entity with rdfs:label "Usain Bolt"#en has many types, but is not a dbo:Person. Similar for the entity with rdfs:label "Rachid Badouri"#en.
In contrast, the entity with rdfs:label "Teddy Riner"#en is a dbo:Person.
Note: DBpedia-Live content is a moving target, varying with Wikipedia content changes, adjustments in the templates, and other variables. The statements I made above may no longer be true when you read this.

DBpedia Sparql by page template

I am trying to run a query on dbpedia using SPARQL syntax, to look for all pages of a certain template. Doesn't seem to be work, I am looking for all pages with dbpprop:wikiPageUsesTemplate. Does anyone know how to correct this to properly look for templates?
SELECT ?name ?member_Of ?country ?lat ?lng ?link
WHERE {
?x dbpprop:wikiPageUsesTemplate "dbpedia:Template:Infobox_settlement" .
?x a <http://dbpedia.org/ontology/Settlement> .
?x foaf:name ?name .
?x dbpedia-owl:isPartOf ?member_Of.
?x dbpedia-owl:country ?country.
?x geo:lat ?lat .
?x geo:long ?lng .
?x foaf:isPrimaryTopicOf ?link .
}
LIMIT 2500 OFFSET 0
I've also attempted to run it just by the dbprop to no avail.
SELECT * WHERE { ?page dbpprop:wikiPageUsesTemplate <http://dbpedia.org/resource/Template:Infobox_settlement> . ?page dbpedia:name ?name .}
If anyone is trying to do a similar thing, it is also possible via the wiki api, where you can pagananate over all results. http://en.wikipedia.org/w/api.php?action=query&list=embeddedin&eititle=Template:Infobox_settlement
There are at least two problems: (i) you need to use IRIs in places, and not strings; and (ii) you need to use properties that DBpedia uses.
Use IRIs
In
?x a <http://dbpedia.org/ontology/Settlement> .
and
?x foaf:isPrimaryTopicOf ?link .
you've demonstrated that you know that URIs need to be written in full with < and >, or abbreviated with a prefix. However,
?x dbpprop:wikiPageUsesTemplate "dbpedia:Template:Infobox_settlement" .
certainly isn't going to work. It's legal SPARQL, because a string can be the object of a triple, but you almost certainly want an IRI.
Use DBpedia's vocabulary
A query with dbpprop:wikiPageUsesTemplate like this returns no results:
select distinct ?template where {
[] dbpprop:wikiPageUsesTemplate ?template
}
SPARQL results
That's easy enough to check, and quickly confirms that there's no data that can possibly match your query. Where did you find this property? Have you seen it used somewhere? I'm not confident that you can query DBpedia based on infobox templates. DBpedia is not the same as Wikipedia, and even if the Wikipedia API supports it, it doesn't mean that DBpedia has a counterpart. There is a note on DBpedia Data Set Properties that says:
http://xx.dbpedia.org/property/wikiPageUsesTemplate (will be changed to http://dbpedia.org/ontology/wikiPageUsesTemplate)
but that latter property doesn't seem to be in use on the endpoints either. See my answer to Syntax for Sparql query for pages with specific infobox for more details.

Inquiry on example of explicit join in the SPARQL

I have following sparql query(from the book, semantic web primer):
select ?n
where
{
?x rdf:type uni:Course;
uni:isTaughtBy :949352
?c uni:name ?n .
FILTER(?c=?x) .
}
In this case, I guess this code is same as the the following:
Select ?n
Where
{
?x rdf:type uni:course;
uni:isTaughtBy :949352 .
?x uni:name ?n .
}
Does this query lead to coding error?
No, I don't see why it should give you an error or produce wrong results. Just make sure to always use the right case (uni:Course vs. uni:course), as SPARQL is case sensitive.
To be honest, the first version seems rather obscure as it uses a FILTER without a real need for it. That said, you may further slim down your query if you wish:
SELECT ?n
WHERE
{
?x rdf:type uni:Course;
uni:isTaughtBy :949352;
uni:name ?n .
}
However, keep in mind that saving characters does not always lead to improved readability.
For your example yes the queries are identical and there would be no value in using a FILTER over a join.
However the reason why you might use the FILTER form is the difference in semantics between joins and the = operator
Joins require that the values of the variables be exactly the same RDF term, whereas = does value equality - do the values of RDF terms that represent the same value? This is primarily a concern when one/both of the values may have literal values
It's easier to see if you take a specific example, assume ?x=4 and ?c = 4.0 (which is a bad example for your query but illustrates the point)
?x = ?c would give true while a join would give no results because they are not the exact same term