I have this query. It matches anything which has "South" in its name. But I only want the one whose foaf:name is exactly "South".
SELECT Distinct ?TypeLabel
WHERE
{
?a foaf:name "South" .
?a rdf:type ?Type .
?Type rdfs:label ?TypeLabel .
}
a bit late but anyway... I think this is what your looking for:
SELECT Distinct ?TypeLabel Where {
?a foaf:name ?name .
?a rdf:type ?Type .
?Type rdfs:label ?TypeLabel .
FILTER (?name="South"^^xsd:string)
}
you can use FILTER with the xsd types in order to restrict the result.
hope this helps...
cheers!
(Breaking out of comments for this)
Data issues
The issue is the data, not your query. If use the following query:
SELECT DISTINCT ?a
WHERE {
?a foaf:name "Imran Khan" .
}
You find (as you say) "Imran Khan Niazy".
But looking at the dbpedia entry for Imran Khan, you'll see both:
foaf:name "Imran Khan Niazy"
foaf:name "Imran Khan"
This is because RDF allows repeated use of properties.
Cause
"South" had the same issue (album, artist, and oddly 'South Luton'). These are cases where there are both familiar names ("Imran Khan", "South"), and more precise names ("Imran Khan Niazy", "South (album)") for the purposes of correctness or disambiguation.
Resolution
If you want a more precise match try adding a type (e.g. http://dbpedia.org/ontology/MusicalWork for the album).
Beware
Be aware that DBpedia derives from Wikipedia, and the extraction process isn't perfect. This is an area alive with wonky data, so don't assume your query has gone wrong.
That query should match exactly the literal South and not literals merely containing South as a substring. For partial matches you'd go to FILTER with e.g. REGEX(). Your query engine is broken in this sense - which query engine you are working with?
Related
and I am trying to write SPARQL query to find distinct object.
here is the dataset:
<https://permid.org/1-36436064275> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <https://permid.org/1-34414203048> .
<https://permid.org/1-34414203048> <http://permid.org/ontology/person/hasTenureInOrganization> <https://permid.org/1-36436064275> .
my sparql query is like this:
select distinct ?n where {
<https://permid.org/1-36436064275> ?a ?b .
?b ?c ?d .
?d ?e ?n .
}
From the dataset, "?d" is https://permid.org/1-36436064275, which is the visited subject. I want to skip visited subject, so that "?d" is empty, thus "?n" is also empty.
There's a couple of things to address here:
From the dataset, "?d" is https://permid.org/1-36436064275, which is the visited subject.
This happens because your RDF graph is a cycle. The first bit of your SPARQL query is:
<https://permid.org/1-36436064275> ?a ?b .
This binds ?a to rdf:type, and ?b to 1-34414203048. The second part of your query pattern is:
?b ?c ?d .
Since ?b is already bound to 1-34414203048 by the previous pattern, there's only one option for ?c (hasTenureInOrganization) and ?d (1-36436064275). Then the third bit of your query is:
?d ?e ?n .
?d is already bound by the previous pattern, so there's one option for ?e (rdf:type again) and ?n (1-36436064275 again).
I want to skip visited subject, so that "?d" is empty, thus "?n" is
also empty.
That's not how SPARQL works. SPARQL only returns a query result if the entire pattern has a result. If ?n has no value, the query will return an empty result.
Having said that, if you want to ensure that ?d is never equal to the subject that you started your query with, you could simply add a FILTER condition:
FILTER (?d != <https://permid.org/1-36436064275>)
But, like I said in the comments as well, I think you may need to rethink your data model a little bit, and consider the purpose of your query as well.
I am trying to get a dataset that gives me all the data available in a city's climate table but I'm having some trouble.
I was able to get this to work and felt pretty good about myself. When I plug this in on dbpedia's virtuoso client this gives me all the cities that dbpedia has, and all of their countries.
PREFIX dbpedia-owl: <http://dbpedia.org/ontology/>
SELECT DISTINCT ?city_name ?country
WHERE { ?city rdf:type dbpedia-owl:City ;
rdfs:label ?city_name;
dbpedia-owl:country ?country
FILTER (langMatches(lang(?city_name), "EN")) .
}
Update: I have found properties that seem to give what I'm looking for (e.g. dbpedia.org/property/aprHighC) but I'm having trouble adding them to my output.
PREFIX dbpedia-owl: <http://dbpedia.org/ontology/>
SELECT DISTINCT ?city_name ?country ?aprHighC
WHERE { ?city rdf:type dbpedia-owl:City .
?city rdfs:label ?city_name .
?city dbpedia-owl:country ?country
FILTER (langMatches(lang(?city_name), "EN")) .
}
Gives an error: Variable 'aprHighC' is used in the query result set but not assigned. How do I assign it?
For the query to get results in the second query, a city has to have a three properties: rdfs:label, dbpedia-owl:country and dbpedia-owl:climate. Your query pretty much proves that DBPedia data has cities with label and country properties, but not climate. Try the following to see just what properties are found for members of dbpedia-owl:City:
SELECT DISTINCT ?p
WHERE {
?city rdf:type dbpedia-owl:City ;
?p ?o .
}
Note that not all members of dbpedia-owl:City will have these properties, but it gives you a range of what properties are used.
Looking at it the other way, you can ask what entities use the dbpedia-owl:climate property:
SELECT ?s
WHERE {
?s dbpedia-owl:climate ?climate
}
I didn't find any, so it could be the case that the prefix is different than the one you are using? I'd suggest double-checking the property name.
Regardless, it's a good idea to use SPARQL to find what is actually in the data store. And use LIMIT to look at parts of the data without overwhelming the system.
The following query gives the January average daily high (°C). Adding other climate items is as simple as copying the line beginning "OPTIONAL" and changing the item and variable name from janHighC to whatever you are trying to get.
PREFIX dbpedia-owl: <http://dbpedia.org/ontology/>
SELECT * {
{ ?city rdf:type dbo:City .
?city rdf:type schema:City .
?city rdfs:label ?name
}
OPTIONAL {?city dbp:janHighC ?janHighC .}
}
I will note, however, that most cities don't have this information. I had to give up on getting the data this way.
I'm trying to develop a tool in JS for tagging pictures, so I need a set of possible "things" from dbpedia. I already tryed to retrieve this way:
select ?s ?l {
?s a owl:Class .
?s rdf:type ?l
FILTER regex(str(?s), "House", "i").
}
http://dbpedia.org/snorql/?query=select+%3Fs+%3Fl+%7B%0D%0A+++%3Fs+a+owl%3AClass+.%0D%0A+++%3Fs+rdf%3Atype+%3Fl%0D%0A+++FILTER+regex%28str%28%3Fs%29%2C+%22House%22%2C+%22i%22%29.%0D%0A%7D
And also this way:
select ?label
WHERE {
?concept a skos:Concept.
?concept skos:prefLabel ?label.
FILTER regex(str(?label), "^House", "i").
}
http://dbpedia.org/snorql/?query=select+%3Flabel+%0D%0AWHERE+%7B%0D%0A++%3Fconcept+a+skos%3AConcept.%0D%0A++%3Fconcept+skos%3AprefLabel+%3Flabel.%0D%0A++FILTER+regex%28str%28%3Flabel%29%2C+%22%5EHouse%22%2C+%22i%22%29.%0D%0A%7D
In the first case, I just have "instances" of the house "thing", but not the "House" class itself. In the second one, I never retrieve the "house" and the similar thing is "houses". Any alternative for retrieving a better vocabulary based in dbpedia dataset?
If you don't bother to restrict yourself to owl:Thing or to skos:Concept, you can just get things that have a label that contains "house". Rather than using regex, I chose to use contains and lcase, since a string containment could be less expensive than invoking a full regular expression processor.
select ?thing ?label where {
?thing rdfs:label ?label .
filter contains(lcase(?label), "house")
}
SPARQL results (limited to 200)
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.
I have the following SPARQL query:
SELECT ?nationalityLabel WHERE {
dbpedia:Henrik_Ibsen dbpedia-owl:nationality ?nationality .
?nationality rdfs:label ?nationalityLabel .
}
I have checked that Henrik Ibsen exists and that he has the nationality ontology/property on him:
http://dbpedia.org/page/Henrik_Ibsen
And this is an ontology:
http://dbpedia.org/ontology/nationality
A very similar query to this listed here works:
https://stackoverflow.com/a/10248653/1680130
The problem I have is that the query doesn't return any result.
If I could get help solving this it would be great.
Summarized solution:
Both answers were great so upvote to both but landed on Joshua's in the end because informing about dbpedia-owl being cleaner. Optimal solution in my opinion:
First check with dbpedia-owl for birth-place:
select ?label {
dbpedia:Henrik_Ibsen
dbpedia-owl:birthPlace
[ a dbpedia-owl:Country ;
rdfs:label ?label ]
filter langMatches(lang(?label),"en")
}
If found then get the demonym:
select ?label {
dbpedia:Norway dbpedia-owl:demonym ?label
filter langMatches(lang(?label),"en")
}
If above fails then do the "dirty" query:
SELECT
?nationality
WHERE {
dbpedia:Henrik_Ibsen dbpprop:nationality ?nationality .
filter langMatches(lang(?nationality),"en")
}
Of course is "dirty" means data being correct but not so often present the order might be better other way around because people can be born in a country but from a different.
Kristian's answer is right that the property is dbpprop:nationality that Henrik Ibsen has. You're right that there is a dbpedia-owl:nationality property, too, but Henrik Ibsen doesn't have a value for it, unfortunately. The value of dbpprop:nationality that Henrik Ibsen has, though, is a string, which is a literal, and literals cannot be the subjects of triples in RDF, so ?nationality rdfs:label ?nationalityLabel in your query will never match.
The DBpedia ontology data (dbpedia-owl) tends to be cleaner than the dbpprop data, so you might prefer a solution using dbpedia-owl properties that Henrik Ibsen does have. In this case, you might look to the dbpedia-owl:birthPlace. Then you could get the name the country of the birth places:
select ?label {
dbpedia:Henrik_Ibsen
dbpedia-owl:birthPlace
[ a dbpedia-owl:Country ;
rdfs:label ?label ]
}
SPARQL results
You might want to narrow the permissible languages:
select ?label {
dbpedia:Henrik_Ibsen
dbpedia-owl:birthPlace
[ a dbpedia-owl:Country ;
rdfs:label ?label ]
filter langMatches(lang(?label),"en")
}
SPARQL results
Those queries will produce the name of the country, but it wanted the corresponding demonym, you can get the dbpedia-owl:demonym value of the country, if it's available. It's probably best to make the demonym optional, since a cursory investigation suggests that lots of countries in DBpedia don't have a value for it, so the name of the country may be the only option. E.g.,
select ?name ?demonym {
dbpedia:Henrik_Ibsen dbpedia-owl:birthPlace ?country .
?country a dbpedia-owl:Country ; rdfs:label ?name .
optional { ?country dbpedia-owl:demonym ?demonym }
filter langMatches(lang(?name),"en")
filter langMatches(lang(?demonym),"en")
}
SPARQL results
Two things are wrong with the query:
It's dbpprop:nationality
The label doesn't appear to exist, and unless you make that variable optional, it will eliminate the row altogether. EDIT: *Joshua Taylor's answer reminded me that the label doesn't exist because the dbprop:nationality value is a literal, which cannot be used as a subject resource, therefore, there will never be a label for dbpprop:nationality. Instead, where the data exists, you would use dbpedia-owl:nationality, which you did originally. it just so happens that Henrik_Ibsen has no dbpedia-owl:nationality value associated with him*
Updated query (updated).
SELECT
#### ?label #### See Edit
?nationality
WHERE {
dbpedia:Henrik_Ibsen dbpprop:nationality ?nationality .
#### OPTIONAL { ?nationality rdfs:label ?label . } #### See Edit.
}