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')) }
}
Related
I created this query to return all books that are notable works by George Orwell but it returns no result.
PREFIX dbo: <http://dbpedia.org/ontology/>
PREFIX dbp: <http://dbpedia.org/resource/>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name ?title where {
?person foaf:name ?name .
?title dbo:author ?person .
?title dbo:notableWork dbp:George_Orwell .
}
I cannot seem to figure out why there is no result.
I am running the query in http://dbpedia.org/snorql
Don't you have the triples about notable works in the wrong order?
Try rewriting based on this working query
SELECT *
WHERE {
:George_Orwell dbo:notableWork ?title
}
.
title
:Nineteen_Eighty-Four
:Animal_Farm
You can also bind :George_Orwell to a variable and ask more about that:
SELECT *
WHERE {
values ?author { :George_Orwell } .
?author rdfs:label ?l .
?title ?p ?author .
?title rdf:type dbo:Book .
filter (lang(?l) = "en")
}
and DESCRIBE things
describe :Animal_Farm
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")
}
how can i get list of book from Wikibooks with SPARQL query fo example :
PREFIX dbo:http://dbpedia.org/ontology/
PREFIX dba:http://dbpedia.org/ontology/
SELECT ?author ?name ?label ?text ?title ?isbn ?publisher ?literaryGenre ?pages WHERE
{?book a dbo:Book.
?book dbo:author ?author.
?book dbo:numberOfPages ?pages.
?book dbp:title ?title.
?book dba:isbn ?isbn.
?book dba:publisher ?publisher.
FILTER regex(?title , "java") .
}
I'm wondering whether you know that Wikibooks is not Wikipedia and DBpedia is based on Wikipedia?!
And then, why do you have two prefixes dbo and dba for the same namespace http://dbpedia.org/ontology/ ? I really suggest to understand what you're doing and what the query does instead of copy and paste from some other sources. SPARQL and RDF tutorials might help, and also the official documentation is useful.
Next issue, you SELECT variables ?name, ?label, ?text and ?literaryGenre which are not bound in a triple pattern in the WHERE part. It's also not clear what you expect to get for ?text. The whole text of the book?! For sure, this won't exist, think about copyrights.
And what would be the difference between ?name and ?title? I don't think that dbp:title is the appropriate property here, see
PREFIX dbo: <http://dbpedia.org/ontology/>
PREFIX dbp: <http://dbpedia.org/property/>
SELECT count(*) WHERE {
?book a dbo:Book ;
dbp:title ?title.
}
which returns 19 only.
My suggestion:
PREFIX dbo: <http://dbpedia.org/ontology/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT * WHERE {
?book a dbo:Book .
?book dbo:author ?author .
OPTIONAL { ?book dbo:numberOfPages ?pages }
OPTIONAL { ?book dbo:isbn ?isbn }
OPTIONAL { ?book dbo:publisher ?publisher }
# get the English title
?book rdfs:label ?name.
FILTER(LANGMATCHES(LANG(?name), 'en'))
# get an English description, but not the text
?book rdfs:comment ?text .
FILTER(LANGMATCHES(LANG(?text), 'en'))
# filter for books whose title contains "java"
FILTER regex(str(?name) , "java", "i") .
}
More efficient using the Virtuoso fulltext index predicate bif:contains:
PREFIX dbo: <http://dbpedia.org/ontology/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT * WHERE {
?book a dbo:Book .
?book dbo:author ?author .
OPTIONAL { ?book dbo:numberOfPages ?pages }
OPTIONAL { ?book dbo:isbn ?isbn }
OPTIONAL { ?book dbo:publisher ?publisher }
# get the English title
?book rdfs:label ?name.
FILTER(LANGMATCHES(LANG(?name), 'en'))
# get an English description, but not the text
?book rdfs:comment ?text .
FILTER(LANGMATCHES(LANG(?text), 'en'))
# filter for books whose title contains "java"
?name bif:contains '"java"'
}
As a book might have multiple authors resp. publisher you might get duplicate rows, here GROUP_BY in combination with GROUP_CONCAT is the way to go (grouped by book):
PREFIX dbo: <http://dbpedia.org/ontology/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT ?book (group_concat(DISTINCT ?author; separator = ", ") as ?authors) (group_concat(DISTINCT ?publisher; separator = ", ") as ?publishers) (sample(?pages) as ?numPages) (sample(?isbn_tmp) as ?isbn) WHERE {
?book a dbo:Book .
?book dbo:author ?author .
OPTIONAL { ?book dbo:numberOfPages ?pages }
OPTIONAL { ?book dbo:isbn ?isbn_tmp }
OPTIONAL { ?book dbo:publisher ?publisher }
# get the English title
?book rdfs:label ?name.
FILTER(LANGMATCHES(LANG(?name), 'en'))
# get an English description, but not the text
?book rdfs:comment ?text .
FILTER(LANGMATCHES(LANG(?text), 'en'))
# filter for books whose title contains "java"
?name bif:contains '"java"'
}
GROUP BY ?book
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 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.