I created a SPARQL query that I'm running on the DBpedia SNORQL SPARQL endpoint. The purpose of the query is to get a list of universities or colleges in the United States, including their longitude, latitude, and endowment. The query seems to be working but seems to be missing some records and/or attributes. So, for example, Harvard University doesn't show up in the result, even though its DBpedia record exists and the attributes should match my query. I'm not sure why that record doesn't show up. Another example is University of Massachusetts Boston, which comes up as a query result, but the result doesn't get the longitude and latitude attributes, even though the record contains those attributes. Here's the SPARQL Query:
PREFIX geo: <http://www.w3.org/2003/01/geo/wgs84_pos#>
PREFIX d: <http://dbpedia.org/ontology/>
SELECT ?uni ?link ?lat ?long ?endowment
WHERE {
?s foaf:homepage ?link ;
rdf:type <http://schema.org/CollegeOrUniversity> ;
rdfs:label ?uni
OPTIONAL {?s geo:lat ?lat ;
geo:long ?long .
?s d:endowment ?endowment . }
FILTER (LANGMATCHES(LANG(?uni), 'en'))
{?s dbpedia2:country "U.S."#en . }
UNION
{?s dbpedia2:country "U.S." . }
UNION
{?s d:country :United_States . }
}
ORDER BY ?s
The query you posted will only select entities with a foaf:homepage and Harvard University does not have one. (That is, the resource does not have a foaf:homepage property. Obviously the university does have a homepage.) UMass Boston doesn't match the optional pattern --
OPTIONAL {?s geo:lat ?lat ;
geo:long ?long .
?s d:endowment ?endowment . }
-- because that pattern only matches when ?s has a geo:lat, a geo:long, and a d:endowment. Though the pattern is optional, the whole pattern must either match or not; you do not get partial matches.
Here's your query, reworked to use the built-in namespaces that the DBPedia SPARQL endpoint currently supports (that list is subject to change over time), with the OPTIONAL parts broken down as necessary, and moved to the end. (Moving them to the end is just an aesthetic consideration.) I tried some various constraints, and it is interesting to note that only 32 universities have the dbpprop:country "U.S."#en, but 273 have dbpprop:country "United States"#en. There are 7620 results in total.
PREFIX dbpedia-owl: <http://dbpedia.org/ontology/>
PREFIX dbpedia: <http://dbpedia.org/resource/>
PREFIX dbpprop: <http://dbpedia.org/property/>
SELECT ?label ?homepage ?lat ?long ?endowment
WHERE {
?school a <http://schema.org/CollegeOrUniversity>
{ ?school dbpedia-owl:country dbpedia:United_States }
UNION
{ ?school dbpprop:country dbpedia:United_States }
UNION
{ ?school dbpprop:country "U.S."#en }
UNION
{ ?school dbpprop:country "United States"#en }
OPTIONAL { ?school rdfs:label ?label .
FILTER (LANGMATCHES(LANG(?label), 'en')) }
OPTIONAL { ?school foaf:homepage ?homepage }
OPTIONAL { ?school geo:lat ?lat ; geo:long ?long }
OPTIONAL { ?school dbpedia-owl:endowment ?endowment }
}
SPARQL Results
You are looking for foaf:homepage but some of them do not have this assigned. That is the first thing that caught my eyes. Check the rest of the query by removing bit by bit each element and see what the result set has to offer.
Related
I am struggling a lot to create some SPARQL queries. I need 3 specific things, and this is what i have so far:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX dbpedia: <http://dbpedia.org/resource/>
PREFIX dbo: <http://dbpedia.org/ontology/>
PREFIX dbp: <http://dbpedia.org/property/>
select distinct ?title ?author ?country ?genre ?language
where {
?s rdf:type dbo:Book;
dbp:title ?title;
dbp:author ?author;
dbp:country ?country;
dbp:genre ?genre;
dbp:language ?language.
}
This query will bring me a list of all books. What i really need is the ability to add some filters to this code. There are 3 things i want to filter by:
specific title name (e.g., search for title with "harry potter")
specific author name (e.g., search for author with "J. K. Rowling")
specific genre (e.g., search for genre with "adventure")
I've been struggling with this for too long and i simply cannot define these 3 queries. I am trying to implement a function that will execute a SPARQL statement using parameters passed by an user form. I found a few examples here and in the web but i just cannot build these 3 specific queries.
As noted, not every book has every property, and some of your properties may not exist at all. For instance, I changed dbp:genre to dbo:literaryGenre, based on the description of Harry Potter and the Goblet of Fire. See query form, and results.
SELECT *
WHERE
{ ?s rdf:type dbo:Book .
?s rdfs:label ?bookLabel .
FILTER(LANGMATCHES(LANG(?bookLabel), 'en'))
?s dbo:author ?author .
?author rdfs:label ?authorLabel .
FILTER(LANGMATCHES(LANG(?authorLabel), 'en'))
?authorLabel bif:contains "Rowling"
OPTIONAL { ?s dbp:country ?country .
?country rdfs:label ?countryLabel .
FILTER(LANGMATCHES(LANG(?countryLabel), 'en')) }
OPTIONAL { ?s dbo:literaryGenre ?genre .
?genre rdfs:label ?genreLabel .
FILTER(LANGMATCHES(LANG(?genreLabel), 'en')) }
OPTIONAL { ?s dbp:language ?language .
?language rdfs:label ?languageLabel .
FILTER(LANGMATCHES(LANG(?languageLabel), 'en')) }
}
I need a sparql query that given a free text (user input),
it finds me from dbpedia all the classes related to it.
How do it?
Also asked here. Accepted answer said --
When you say classes, are you mean about types? If yes, try something like
SELECT ?uri ?label ?type
WHERE {
?uri rdfs:label ?label .
?uri <http://dbpedia.org/ontology/type> ?type .
FILTER regex(str(?label), "Leipzig") .
}
limit 10
I couldn't let this go...
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX virtdrf: <http://www.openlinksw.com/schemas/virtrdf#>
SELECT ?s1c AS ?c1
COUNT (*) AS ?c2
?c3
WHERE
{
QUAD MAP virtrdf:DefaultQuadMap
{
GRAPH ?g
{
?s1 ?s1textp ?o1 .
?o1 bif:contains '"dbpedia"' .
}
}
?s1 a ?s1c .
OPTIONAL { ?s1c rdfs:label ?c3
FILTER(langMatches(LANG(?c3),"EN"))}
}
GROUP BY ?s1c ?c3
ORDER BY DESC (2) ASC (3)
The earlier answer gets you partial results.
I'm developing my own Fuseki endpoint from some DBpedia data.
I'm in doubt on how to aggregate properties related to a single resource.
SELECT ?name ?website ?abstract ?genre ?image
WHERE{
VALUES ?s {<http://dbpedia.org/resource/Attack_Attack!>}
?s foaf:name ?name ;
dbo:abstract ?abstract .
OPTIONAL { ?s dbo:genre ?genre } .
OPTIONAL { ?s dbp:website ?website } .
OPTIONAL { ?s dbo:image ?image } .
FILTER LANGMATCHES(LANG(?abstract ), "en")
}
SPARQL endpoint: http://dbpedia.org/sparql/
This query returns 2 matching results. They are different just for the dbo:genre value. There is a way I can query the knowledge base and retrieving a single result with a list of genres?
#chrisis's query works well on the DBpedia SPARQL Endpoint, which is based on Virtuoso.
However, if you are using Jena Fuseki, you should use more conformant syntax:
PREFIX dbo: <http://dbpedia.org/ontology/>
PREFIX dbp: <http://dbpedia.org/property/>
SELECT
?name
(SAMPLE(?website) AS ?sample_website)
(SAMPLE(?abstract) AS ?sample_abstract)
(SAMPLE(?image) AS ?sample_image)
(GROUP_CONCAT(?genre; separator=', ') AS ?genres)
WHERE {
VALUES (?s) {(<http://dbpedia.org/resource/Attack_Attack!>)}
?s foaf:name ?name ;
dbo:abstract ?abstract .
OPTIONAL { ?s dbo:genre ?genre } .
OPTIONAL { ?s dbp:website ?website } .
OPTIONAL { ?s dbo:image ?image} .
FILTER LANGMATCHES(LANG(?abstract ), "en")
} GROUP BY ?name
The differences from the #chrisis's query are:
Since GROUP_CONCAT is an aggregation function, it might be used with GROUP BY only;
Since GROUP BY is used, all non-grouping variables should be aggregated (e.g. via SAMPLE);
GROUP_CONCAT syntax is slightly different.
In Fuseki, these AS in the projection are in fact superfluous: see this question and comments.
Yes, the GROUP_CONCAT() function is what you want.
SELECT ?name ?website ?abstract (GROUP_CONCAT(?genre,',') AS ?genres) ?image
WHERE{
<http://dbpedia.org/resource/Attack_Attack!> a dbo:Band ;
foaf:name ?name;
dbo:abstract ?abstract .
OPTIONAL{ <http://dbpedia.org/resource/Attack_Attack!> dbo:genre ?genre } .
OPTIONAL{ <http://dbpedia.org/resource/Attack_Attack!> dbp:website ?website} .
OPTIONAL{ <http://dbpedia.org/resource/Attack_Attack!> dbo:image ?image} .
FILTER LANGMATCHES(LANG(?abstract ), "en")
}
I'm a beginner in SPARQL. And I'm having problems to get the latitude and longitude of all university by city on DBpedia.
I tried multiple things without success.
This page shows the universities of Paris on the dbo:campus property, so I like to get the list of the universities with this property and after that get the geographics coordinates.
PREFIX geo: <http://www.w3.org/2003/01/geo/wgs84_pos#>
PREFIX dbo: <http://dbpedia.org/ontology/>
SELECT ?name, ?univ, ?lat, ?long WHERE {
?p rdf:type dbo:Place.
?p rdfs:label ?name.
?p dbo:campus ?u.
?u geo:lat ?lat.
?u geo:long ?long.
?u rdfs:label ?univ
FILTER(LANG(?name) = "en").
FILTER(?name = "Paris")
}
I check this post DBpedia SPARQL Query US Universities but it doesn't work with another country.
If you read "is SOME_PROPERTY of"on a rendered DBpedia page, this means the inverse direction, i.e., it shows the triple in its inverted form. Thus, you have to invert the triple pattern in the SPARQL query. For your example, it means that universities are the subject and Paris the object:
?u dbo:campus ?p
The labels are language tagged in DBpedia; thus, FILTER(?name = "Paris") is not enough. Adding the English language tag helps:
FILTER(?name = "Paris"#en)
A working query would be
PREFIX geo: <http://www.w3.org/2003/01/geo/wgs84_pos#>
PREFIX dbo: <http://dbpedia.org/ontology/>
SELECT ?name, ?univ WHERE {
?p rdf:type dbo:Place.
?p rdfs:label ?name.
?u dbo:campus ?p.
?u geo:lat ?lat.
?u geo:long ?long.
?u rdfs:label ?univ
FILTER(LANG(?name) = "en").
FILTER(?name = "Paris"#en)
}
Some comments:
Using the label to match a resource can lead to unwanted results. Resources are identified by URIs; thus, use the URI if possible. The VALUES clause is a cool feature of SPARQL 1.1 to support inline data.
If you use the URI, you could omit the rdf:type triple pattern since you wouldn't have to filter for resources of a specific type given the label.
The official SPARQL standard doesn't allow commas in between the projection variables; this is Virtuoso-specific syntax.
SPARQL supports the more compact Turtle syntax.
A FILTER doesn't need a . at the end.
Try to use LANGMATCHES for matching languages in literals.
A "better" query could be:
PREFIX geo: <http://www.w3.org/2003/01/geo/wgs84_pos#>
PREFIX dbo: <http://dbpedia.org/ontology/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX dbr: <http://dbpedia.org/resource/>
SELECT ?name ?univ ?lat ?long
WHERE
{ VALUES ?p { dbo:Paris }
?p rdfs:label ?name .
?u dbo:campus ?p ;
geo:lat ?lat ;
geo:long ?long ;
rdfs:label ?univ
FILTER langMatches(lang(?name), "en")
}
I am trying to query dbpedia to get some people data and I don't have subjects just names of the people I want to query and their birth/death dates.
I am trying to do a query along these lines. I want the name, birth date, death date and thumbnail of everyone with the surname Presley. What I then intend to do is loop through the results returned and find the best match for Elvis Presley 1935-1977 which is the data I have.
PREFIX dbo: <http://dbpedia.org/ontology/>
SELECT ?Name ?thumbnail ?birthDate ?deathDate WHERE {
{
dbo:name ?Name ;
dbo:birthDate ?birthDate ;
dbo:birthDate ?deathDate ;
dbo:thumbnail ?thumbnail ;
FILTER contains(?Name#en, "Presley")
}
What is the best way to construct my sparql query?
UPDATE:
I have put together this query which seems to work to some extent but I don't entirely understand it, and I can't figure out the contains, but it does at least run and return results.
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX dbo: <http://dbpedia.org/ontology/>
SELECT ?subject ?thumbnail ?birthdate ?deathdate WHERE {
{
?subject rdfs:label "Elvis Presley"#en ;
dbo:thumbnail ?thumbnail ;
dbo:birthDate ?birthdate ;
dbo:deathDate ?deathdate ;
a owl:Thing .
}
UNION
{
?altName rdfs:label "Elvis Presley"#en ;
dbo:thumbnail ?thumbnail ;
dbo:birthDate ?birthdate ;
dbo:deathDate ?deathdate ;
dbo:wikiPageRedirects ?s .
}
}
Some entities might not have all of that information, so it's better to use optional. You can use foaf:surname to check for surname directly.
select * where {
?s foaf:surname "Presley"#en
optional { ?s dbo:name ?name }
optional { ?s dbo:birthDate ?birth }
optional { ?s dbo:deathDate ?death }
optional { ?s dbo:thumbnail ?thumb }
}