Retrieve the US release date for a movie from Wikidata using Sparql - sparql

I am trying to retrieve the titles and release dates (publication date) for movies using the wikidata.org sparkql endpoint (https://query.wikidata.org/). The titles are listed in different languages, which are filtered in the query below. However, some movies also have several publication dates (e.g. for different countries), e.g. https://www.wikidata.org/wiki/Q217020. I'm not sure how the RDF triple structure is actually used to assign a country to the value of another triple, but specifically, how can I only retrieve the publication date for a movie in the US?
SELECT ?item ?title ?publicationdate
WHERE {
?item wdt:P31 wd:Q11424 ;
rdfs:label ?title ;
wdt:P577 ?publicationdate ;
filter ( lang(?title) = "en" )
}
ORDER BY ?movieid
LIMIT 10
Solution
The solution provided by M.Sarmini works. Apparently, facts such as publication data are stored as n-ary relations, they create a unique symbolic tag that links the resources. The value that P577 links to is just the date, when turned into a string will give the release date, while in reality it is a token that you can link to other qualifiers.

Just add a new variable to hold the place of publication and filter your results to just list US films like this:
PREFIX q: <http://www.wikidata.org/prop/qualifier/>
PREFIX s: <http://www.wikidata.org/prop/statement/>
SELECT distinct ?item ?title ?publicationdate
WHERE {
?item wdt:P31 wd:Q11424;
rdfs:label ?title;
p:P577 ?placeofpublication.
?placeofpublication q:P291 wd:Q30.
?placeofpublication s:P577 ?publicationdate;
filter ( lang(?title) = "en")
}
ORDER BY ?item

Related

Retrieving Covid-19 pandemic statistics per country from DBpedia

I'm trying to get the arrival date, the confirmed and recovery cases total and the deaths total of Covid-19 pandemic per country from DBpedia, using this query:
PREFIX dbp: <http://dbpedia.org/property/>
SELECT distinct ?country ?arrivalDate ?confirmedCases ?recoveryCases ?deaths WHERE {
?country a dbp:location;
dbp:arrivalDate ?arrivalDate;
dbp:confirmedCases ?confirmedCases;
dbp:recoveryCases ?recoveryCases;
dbp:deaths ?deaths
}
Unfortunately, it doesn't return anything
?country a dbp:location
With this triple pattern, you are trying to find entities that have http://dbpedia.org/property/location as type (rdf:type). This is not what you intend, because
dbp:location is a property (not a class), and
in the subject position, you don’t seem to want to find locations, but information about the pandemic.
So ideally rename ?country to something like ?pandemicInfo (for clarity), and then ask for the dbp:location of that ?pandemicInfo:
SELECT DISTINCT ?pandemicInfo ?country ?arrivalDate ?confirmedCases ?recoveryCases ?deaths
WHERE {
?pandemicInfo
dbp:location ?country ;
dbp:arrivalDate ?arrivalDate ;
dbp:confirmedCases ?confirmedCases ;
dbp:recoveryCases ?recoveryCases ;
dbp:deaths ?deaths .
}
To only get information about the COVID-19 pandemic, you could add:
dbo:disease dbr:COVID-19
And if there is a type that all entities share, e.g., dbo:Pandemic, you could add:
a dbo:Pandemic
(But you should verify if all the entities you are interested in contain these statements, otherwise you would exclude them.)

How to get the number of languages a Wikipedia page is available in? (SPARQL query)

I'm trying to have a list of Italian books from the 1980 on and the number of Wikipedia pages their original Wikipedia page has been translated into, for instance I would like to have:
Book, number
The name of the Rose, 5
Where 5 is the number of languages The Name of the Rose has been translated into in Wikipedia, for instance there is an English wiki page, a Dutch one, a Spanish one, a French one, a Greek one.
Here is the query so far:
SELECT ?item ?label
WHERE
{
VALUES ?type {wd:Q571 wd:Q7725634} # book or literary work
?item wdt:P31 ?type .
?item wdt:P577 ?date FILTER (?date > "1980-01-01T00:00:00Z"^^xsd:dateTime) . #dal 1980
?item rdfs:label ?label filter (lang(?label) = "it")
?item wdt:P495 wd:Q38 .
}
I get the list of books, but I can't find the right property to look for.
Did you actually get The Name of the Rose in your example? Because its date of publication is set to 1980 (which is = 1980-01-01 for our purposes), I had to change your query to a >= comparison.
Then, using COUNT() and GROUP BY as mentioned in the comment gets you what you want. But if you really just need the number of sitselinks, there is a shortcut that may be useful. It was added because that number is often used as a good proxy for an item's popularity, and using the precomputed number is vastly more efficient than getting all links, grouping, and counting.
SELECT ?book ?bookLabel ?sitelinks ?date WHERE {
VALUES ?type { wd:Q571 wd:Q47461344 wd:Q7725634 }
?book wdt:P31 ?type;
wdt:P577 ?date;
wdt:P495 wd:Q38;
wikibase:sitelinks ?sitelinks.
FILTER((?date >= "1980-01-01T00:00:00Z"^^xsd:dateTime) && (?date < "1981-01-01T00:00:00Z"^^xsd:dateTime))
SERVICE wikibase:label { bd:serviceParam wikibase:language "it,en". }
}
Query
Note that the values may slightly differ from the version with group & count because here sites such as commons or wikiquote are also included.

Wikidata: Get all non-classical Musicians via SPARQL query

I hope that this kind of question is allowed here as it is more a Wikidata specific question. Anyways, I try to get all non-classical-music musicians from Wikidata by SPARQL. Right now I have this code:
SELECT ?value ?valueLabel ?born WHERE {
{
SELECT DISTINCT ?value ?born WHERE {
?value wdt:P31 wd:Q5 . # all Humans
?value wdt:P106/wdt:P279* wd:Q639669 . # of occupation or subclass of occupation is musician
?value wdt:P569 ?born . # Birthdate
FILTER(?born >= "1981-01-01T00:00:00Z"^^xsd:dateTime) # filter by Birthyear
}
ORDER BY ASC(?born)
#LIMIT 500
}
SERVICE wikibase:label { bd:serviceParam wikibase:language "en,ger". }
}
this gets me (theoretically) all People whose occupation is Musician (https://www.wikidata.org/wiki/Q639669) and who were born after 1900. (Theoretically because this query runs way too long and I had to break it into smaller chunks)
What I am after however is to exclude People who are primary classical musicians. Is there any property I am not aware of? Otherwise, how would I change my query to be able to filter by specific properties (like Q21680663, classical composer)?
Thanks!
If you check the Examples tab in the query interface and type music into the search field, you'll find an example that almost hits the spot:
Musicians or singers that have a genre containing 'rock'.
I've used that mostly to just get a list of all musicians with their genres. I finally settled on a MINUS query subtracting any musician who touches western classical music or baroque music, the latter included specifically to get Bach, the old bastard.
SELECT DISTINCT
?human ?humanLabel
(GROUP_CONCAT(DISTINCT ?genreLabel; SEPARATOR = ", ") AS ?genres)
WHERE {
{
?human wdt:P31 wd:Q5;
wdt:P106 wd:Q639669;
wdt:P136 ?genre.
} MINUS {
VALUES ?classics {
wd:Q9730
wd:Q8361
}
?human wdt:P136 ?classics.
}
# This is just boilerplate to get the labels.
# it's slightly faster this way than the label
# service, and the query is close to timing out already
?genre rdfs:label ?genreLabel.
FILTER((LANG(?genreLabel)) = "en")
?human rdfs:label ?humanLabel.
FILTER((LANG(?humanLabel)) = "en")
}
GROUP BY ?humanLabel ?human
In the Query Interface: 25,000 results in 20sec
Here's a taste of what the results look like (from some intermediate version, because I'm not redoing the table now).
artist
genres
Gigi D'Agostino
Latin jazz, Italo dance
Erykah Badu
neo soul, soul music
Yoko Kanno
jazz, blues, pop music, J-pop, film score, New-age music, art rock, ambient music
Michael Franks
pop music, rock music
Harry Nilsson
rock music, pop music, soft rock, baroque pop, psychedelic rock, sunshine pop
Yulia Nachalova
jazz, pop music, soul music, contemporary R&B, blue-eyed soul, estrada
Linda McCartney
pop rock
From the original example, you may want to try also including singers. The following, replacing the existing line with "P106" does that, and results in about twice as many results. But it often times out.
VALUES ?professions {
wd:Q177220
wd:Q639669
}
wdt:P106 ?professions;
Query including singers, 53,000 results but may time out
The example also uses the following to cut down results rather drastically, by including only items with a certain number of statements, assuming those correlate with... something. You may want to experiment with it to focus on the most significant results, or to give you room to avoid the timeout with other changes. Maybe trying lower limits than 50 to find the right balance is a good idea, though.
?human wikibase:statements ?statementcount.
FILTER(?statementcount > 50 )
A query with singers and the statement limit
This is an earlier version. It excludes all the listed genres, but includes any musician linked to any other genre, and there are many of them that would probably qualify as "classics". The filter uses the "NOT IN" construct, which seems cleaner to me than filtering based on labels.
SELECT DISTINCT
?human ?humanLabel
(GROUP_CONCAT(DISTINCT ?genreLabel; SEPARATOR = ", ") AS ?genres)
WHERE {
?human wdt:P31 wd:Q5;
wdt:P106 wd:Q639669;
wdt:P136 ?genre.
# The "MAGIC": Q9730 is "Western Classical Music"
# Q1344 is "opera"
# Then I noticed Amadeus, Wagner, and Bach all slipped through and expanded the list, and it's a really
# ugly way of doing this
FILTER(?genre NOT IN(wd:Q9730, wd:Q1344, wd:Q9734, wd:Q9748, wd:Q189201, wd:Q8361, wd:Q2142754, wd:Q937364, wd:Q1546995, wd:Q1746028, wd:Q207338, wd:Q3328774, wd:Q1065742))
?genre rdfs:label ?genreLabel.
FILTER((LANG(?genreLabel)) = "en")
?human rdfs:label ?humanLabel.
FILTER((LANG(?humanLabel)) = "en")
}
GROUP BY ?humanLabel ?human
This gets me 26,000 results. View in Query Interface
Note that this will still return artists that have "western classical music" among their genres, aw long as they are also linked to other genres. To exclude any musician ever dabbling in the classics, you'll have to start a daytime top-30 radio station use a MINUS construct to, essentially, subtract all those.

Wikidata Query misses results

I am trying to query all the countries from Wikidata (query link):
SELECT ?item WHERE { ?item wdt:P31 wd:Q6256. }
Unfortunately, the results are missing for example Switzerland (Q39):
https://www.wikidata.org/wiki/Q39
Looking at the Switzerland data, it has the triple: instance of (P31) country (Q6256).
Could you help me understand why Q39 is not present in the results then?
Thanks!
In WikiData, often you have what are called statements. These allow for qualifications to those statements.
For instance, in the case of Switzerland being a country, the qualification is that the rank of this statement should be 'normal' instead of preferred.
The preferred way to refer to Switzerland is sovereign state (wd:Q3624078), and it looks like WikiData will only have a wdt:P31 relationship between an entity and its 'preferred rank' classification only, as this query shows.
I think this could be because 'country' is a more generic concept, e.g. Wales is a country but not a sovereign state.
Fear not however, as this query:
SELECT DISTINCT ?item
WHERE {
?item p:P31/ps:P31 wd:Q6256.
}
returns wd:Q39 as well. What this query is doing is to navigate from Switzerland to Country via the statement.
That is, we have in our data:
wd:Q39 p:P31 wds:Q39-fbe1ac75-4a8a-93c4-6009-81055d79f9cb .
wds:Q39-fbe1ac75-4a8a-93c4-6009-81055d79f9cb ps:P31 wd:Q6256 .
but not:
wd:Q39 wdt:P31 wd:Q6256 .
Try this:
SELECT DISTINCT *
WHERE {
?item p:P31 ?y .
?y ps:P31 wd:Q6256 ;
?p ?o .
VALUES ?item {wd:Q39}
}
to see for yourself.

How to convert some queries from sql to sparql?

I am just learning Sparql and I have the following tables:
Countries, European Country, City and Capital
I would like to know how to make the following queries, because I didnt understand them...
1) Which country has the city "Paris" as capital.
2) Print all the European Countries
3) Print all the countries and theis capitals.
Thank you very much in advance.
This said, there is DBpedia that offers info similar to what is described, and is a good playground. To query it, http://yasgui.org (which is a better sparql editor) or http://factforge.net/sparql (which is our own integration, a few months old, but has some extra goodies).
Which country has the city "Paris" as capital
select * {
?x a dbo:Country; dbo:capital dbr:Paris
}
The yasgui results will surprise you:
dbr:Bourbon_Restoration
dbr:France
dbr:Francia
dbr:French_Fifth_Republic
dbr:Kingdom_of_France
dbr:Office_International_d'Hygiène_Publique
dbr:Second_French_Empire
dbr:West_Francia
I understand all the historic kingdoms, but dbr:Office_International_d'Hygiène_Publique is a bit of a shock. The reason is that it's an International Organization (uses Infobox Former International Organization, and it redirects to https://en.wikipedia.org/wiki/Template:Infobox_former_country, which "is currently being merged with Template:Infobox country". See http://mappings.dbpedia.org/index.php/Cleaning_up_Countries
factforge returns even more results from linked datasets (all these mean just France):
geodata:3017382/
http://ontologi.es/place/FR
http://psi.oasis-open.org/iso/3166/#250
leaks:country-FRA
wfr:fr
All the European Countries
That's better because there happens to be a Wikipedia category:
select * {
?x a dbo:Country; dct:subject dbc:Countries_in_Europe
}
yasgui
all countries and their capitals
select * {
?x a dbo:Country; dbo:capital ?capital
}
This returns a bunch of historic countries and capitals, and again some international organizations, eg
League_of_Nations
International_Authority_for_the_Ruhr
Japanese_occupation_of_British_Borneo
SO THEN, you may have better luck with Wikidata (https://query.wikidata.org/). At https://twitter.com/search?q=wikidatafacts%20country you can find a bunch of interesting queries related to countries.
countries and capitals on Wikidata
select ?country ?countryLabel ?city ?cityLabel {
?country wdt:P36 ?city
filter exists {?country wdt:P31/wdt:P279* wd:Q6256}
SERVICE wikibase:label {
bd:serviceParam wikibase:language "en,pl,ru,es" .
}
} order by ?countryLabel
It uses a bunch of Qnn and Pnn but you can decode them when you mouse-over.
How did I find that wdt:P36 means "capital"? Search for property:capital
why filter exists? Because a country may have several subtypes of wd:Q6256 "country", and if I use that in the main query, it returns several results per country. This way it returns only one.
Map
You can also easily display it on a map:
#defaultView:Map
select ?country ?countryLabel ?city ?cityLabel ?coords {
?country wdt:P36 ?city
filter exists {?country wdt:P31/wdt:P279* wd:Q6256}
?city wdt:P625 ?coords
SERVICE wikibase:label {bd:serviceParam wikibase:language "en,pl,ru,es"}
}
See a couple of shots https://twitter.com/valexiev1/status/844870994942603264