SPARQL Wikidata - Retrieve members of Wikimedia Category - sparql

I want to retrieve the members of the Wikimedia Category American rock singers. I must use Wikidata and it tells me to use P31 with Q4167836 . The query below only returns information about the Category page and not about its members.
Is there any other way to retrieve the members of the Wikimedia Category? I also tried using the term dcterms:subject, which I use successfully with DBpedia, but in Wikidata the query returns empty results.
prefix wdt: <http://www.wikidata.org/prop/direct/>
prefix wd: <http://www.wikidata.org/entity/>
prefix wikibase: <http://wikiba.se/ontology#>
prefix bd: <http://www.bigdata.com/rdf#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT DISTINCT ?subject ?predicate ?object ?objectLabel WHERE {
?subject ?predicate ?object ; wdt:P31 wd:Q4167836 ;
rdfs:label "Category:American rock singers"#en
SERVICE wikibase:label { bd:serviceParam wikibase:language "en" .}
}
Try here

Try this query on Wikidata:
SELECT ?subjectLabel WHERE {
?subject wdt:P27 wd:Q30;
wdt:P136 wd:Q11399 .
SERVICE wikibase:label { bd:serviceParam wikibase:language "en" .}
}
Or try this query on DBpedia (as Mark Miller linked to):
SELECT str(?label) WHERE {
?subject dct:subject dbc:American_rock_singers ;
rdfs:label ?label .
FILTER (lang(?label) = "en")
}
Or if you must use Wikidata, try this federated query on Wikidata:
PREFIX dbc: <http://dbpedia.org/resource/Category:>
PREFIX dct: <http://purl.org/dc/terms/>
SELECT ?wsubjectLabel WHERE {
SERVICE <http://dbpedia.org/sparql> {
?subject dct:subject dbc:American_rock_singers .
?subject owl:sameAs ?wsubject .
FILTER (STRSTARTS(STR(?wsubject), "http://www.wikidata.org"))
}
SERVICE wikibase:label { bd:serviceParam wikibase:language "en" }
}

Related

Get Wikidata entity descriptions via SPARQL, without Wikidata label service

I found this following code snippet on opendata.stackexchange.com, which returns name and description of citizens of the US from Wikidata:
prefix wdt: <http://www.wikidata.org/prop/direct/>
prefix wd: <http://www.wikidata.org/entity/>
PREFIX wikibase: <http://wikiba.se/ontology#>
SELECT ?Name ?itemDescription WHERE {
?item wdt:P27 wd:Q30 .
?item rdfs:label ?Name
SERVICE wikibase:label {
bd:serviceParam wikibase:language "en" .
}
}
LIMIT 3
The query can be evaluated at https://query.wikidata.org/
I am trying to get a description of a particular entity, for example Q3(life). But it in this case, the labelService does not return anything.
prefix wdt: <http://www.wikidata.org/prop/direct/>
prefix wd: <http://www.wikidata.org/entity/>
PREFIX wikibase: <http://wikiba.se/ontology#>
SELECT ?Name ?itemDescription WHERE {
wd:Q3 rdfs:label ?Name
SERVICE wikibase:label { bd:serviceParam wikibase:language "en" }
}
LIMIT 3
EDIT: I am using Virtuoso and therefore cannot rely on Wikidata Label Service.
I am using
PREFIX wd: <http://www.wikidata.org/entity/>
PREFIX schema: <http://schema.org/>
SELECT ?o
WHERE
{
wd:Q3 schema:description ?o.
FILTER ( lang(?o) = "en" )
}
now, since I am querying a Virtuoso Server with Full-Text-Search capabilities, and it would be better to retrieve the description with other properties in one go.

Duplicated results from Wikidata

I created the following SPARQL query to Wikidata. And the result of this query are records related to states in Germany. But as you can see, results are occurring four times in a row (you can test it here: https://query.wikidata.org/). I supposed that there is a problem with geo coordinates and languages but I can't resolve it anyway. What is wrong with this query and how can I fix it to receive a result without repetition?
PREFIX p: <http://www.wikidata.org/prop/>
PREFIX schema: <http://schema.org/>
PREFIX psv: <http://www.wikidata.org/prop/statement/value/>
PREFIX wdt: <http://www.wikidata.org/prop/direct/>
PREFIX wikibase: <http://wikiba.se/ontology#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX wd: <http://www.wikidata.org/entity/>
SELECT DISTINCT ?subject ?featureCode ?countryCode ?name ?latitude ?longitude ?description ?iso31662
WHERE
{ ?subject wdt:P31 wd:Q1221156 ;
rdfs:label ?name ;
wdt:P17 ?countryClass .
?countryClass
wdt:P297 ?countryCode .
?subject wdt:P31/(wdt:P279)* ?adminArea .
?adminArea wdt:P2452 "A.ADM1" ;
wdt:P2452 ?featureCode .
?subject wdt:P300 ?iso31662
OPTIONAL
{ ?subject schema:description ?description
FILTER ( lang(?description) = "en" )
?subject p:P625 ?coordinate .
?coordinate psv:P625 ?coordinateNode .
?coordinateNode
wikibase:geoLatitude ?latitude ;
wikibase:geoLongitude ?longitude
}
FILTER ( lang(?name) = "en" )
FILTER EXISTS { ?subject wdt:P300 ?iso31662 }
}
ORDER BY lcase(?name)
OFFSET 0
LIMIT 200
In short, "9.0411111111111"^^xsd:double and "9.0411111111111"^^xsd:decimal are distinct, though they might be equal in some sense.
Check this:
SELECT DISTINCT ?subject ?featureCode ?countryCode ?name ?description ?iso31662
(datatype(?latitude) AS ?lat)
(datatype(?longitude) AS ?long)
and this:
SELECT DISTINCT ?subject ?featureCode ?countryCode ?name ?description ?iso31662
(xsd:decimal(?latitude) AS ?lat)
(xsd:decimal(?longitude) AS ?long)

SPARQL BIND inside UNION is too slow

Given an IMDb ID, i want to get a list of directors and actors for that movie from Wikidata.
The problem is, I want to UNION both the director and actor query into a single column while also providing a new column with the role of director or actor.
Pretty easy query overall: first I get the movie entity from the IMDb ID, then I get all the directors from that movie followed by getting all the actors from that movie and UNION them together while filling a new column (?role) with the role.
This is what I have:
PREFIX p: <http://www.wikidata.org/prop/>
PREFIX ps: <http://www.wikidata.org/prop/statement/>
PREFIX wdt: <http://www.wikidata.org/prop/direct/>
SELECT ?person ?personLabel ?role ?imdb WHERE
{
?movie wdt:P345 "tt0110912" .
{ ?movie p:P57 ?cast .
?cast ps:P57 ?person .
BIND("director" as ?role) .
} UNION {
?movie p:P161 ?cast .
?cast ps:P161 ?person .
BIND("actor" as ?role) . }
?person wdt:P345 ?imdb .
OPTIONAL { ?cast prov:wasDerivedFrom ?ref . }
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
GROUP BY ?person ?personLabel ?role ?imdb
ORDER BY DESC(?role)
LIMIT 100
This works and gives the result I want, problem is it takes about 10secs. If I remove the BINDs its instant speed, but I don't get a column with the roles.
I'd write this using values instead of bind and union. The idea is that you're saying when the properties are one thing, then ?role is one thing, and when the properties are another, ?role is another. The easy way to do that with values is something like:
select ?owner ?pet ?petType {
values (?hasPet ?petType) {
(:hasCat "cat")
(:hasDog "dog")
}
?owner ?hasPet ?pet
}
In your case, this would be:
PREFIX p: <http://www.wikidata.org/prop/>
PREFIX ps: <http://www.wikidata.org/prop/statement/>
PREFIX wdt: <http://www.wikidata.org/prop/direct/>
SELECT ?person ?personLabel ?role ?imdb WHERE
{
?movie wdt:P345 "tt0110912" .
values (?p ?ps ?role) {
(p:P161 ps:P161 "actor")
(p:P57 ps:P57 "director")
}
?movie ?p ?cast .
?cast ?ps ?person .
?person wdt:P345 ?imdb .
OPTIONAL { ?cast prov:wasDerivedFrom ?ref . }
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
GROUP BY ?person ?personLabel ?role ?imdb
ORDER BY DESC(?role)
LIMIT 100
When I run this at query.wikidata.org, it produces 35 results almost instantly.
I guess that BIND leads to some problems with the query optimizer. You can try as an alternative to bind the role outside of the UNION clause, i.e.
PREFIX p: <http://www.wikidata.org/prop/>
PREFIX ps: <http://www.wikidata.org/prop/statement/>
PREFIX wdt: <http://www.wikidata.org/prop/direct/>
SELECT ?person ?personLabel ?role ?imdb WHERE
{
?movie wdt:P345 "tt0110912" .
?person wdt:P345 ?imdb .
{
?movie p:P57 ?c1 . ?c1 ps:P57 ?person .
?movie p:P57 ?cast .
} UNION {
?movie p:P161 ?c2 . ?c2 ps:P161 ?person .
?movie p:P161 ?cast .
}
BIND(IF(bound(?c1), "director", "actor") as ?role)
OPTIONAL { ?cast prov:wasDerivedFrom ?ref . }
SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}
GROUP BY ?person ?personLabel ?role ?imdb
ORDER BY DESC(?role)
LIMIT 100
(If you do not the ?ref variable, you can omit the triple patterns to retrieve the ?cast in the UNION clauses.)

How to get Wikidata labels in more than one language?

I'm traying to get the regions of Italy in both Italian and English. I can get then in one laguage with this query...
PREFIX wikibase: <http://wikiba.se/ontology#>
PREFIX wd: <http://www.wikidata.org/entity/>
PREFIX wdt: <http://www.wikidata.org/prop/direct/>
SELECT DISTINCT ?RegionIT ?RegionITLabel ?ISO_code ?Geo
{
?RegionIT wdt:P31 wd:Q16110;
wdt:P300 ?ISO_code;
wdt:P625 ?Geo
SERVICE wikibase:label { bd:serviceParam wikibase:language "it" }
}
ORDER BY ?regionITLabel
... but adding another language using the standard SPARQL syntax doesn't work.
... but adding another language using the standard SPARQL syntax doesn't work.
How are you doing that? This works:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX wikibase: <http://wikiba.se/ontology#>
PREFIX wd: <http://www.wikidata.org/entity/>
PREFIX wdt: <http://www.wikidata.org/prop/direct/>
SELECT DISTINCT ?RegionIT ?label (lang(?label) as ?label_lang) ?ISO_code ?Geo
{
?RegionIT wdt:P31 wd:Q16110;
wdt:P300 ?ISO_code;
wdt:P625 ?Geo ;
rdfs:label ?label
}
order by ?RegionIT
Link to try query
To limit to just Italian and English filter on the lang:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX wikibase: <http://wikiba.se/ontology#>
PREFIX wd: <http://www.wikidata.org/entity/>
PREFIX wdt: <http://www.wikidata.org/prop/direct/>
SELECT DISTINCT ?RegionIT ?label ?ISO_code ?Geo
{
?RegionIT wdt:P31 wd:Q16110;
wdt:P300 ?ISO_code;
wdt:P625 ?Geo ;
rdfs:label ?label
filter(lang(?label) = 'it' || lang(?label) = 'en')
}
order by ?RegionIT
Link to try query
Obviously that multiplies the number of results, one for each language. If that's an issue you can do:
...
rdfs:label ?label_it , ?label_en
filter(lang(?label_it) = 'it' && lang(?label_en) = 'en')
...
which is effectively what the language service does.
Let's list all countries in English and Russian.
#List of countries in English and Russian
SELECT ?country ?label_en ?label_ru
WHERE
{
?country wdt:P31 wd:Q6256.
?country rdfs:label ?label_en filter (lang(?label_en) = "en").
?country rdfs:label ?label_ru filter (lang(?label_ru) = "ru").
}
SPARQL query
This example was taken from the tutorial Research in programming Wikidata, section "Countries".

Wikidata SPARQL Query

On Wikidata's SPARQL endpoint, I want to find all the universities where someone was employed as a university teacher. So far, I managed to get the triples of type (person, position helf, employer) with the following query:
PREFIX bd: <http://www.bigdata.com/rdf#>
PREFIX wd: <http://www.wikidata.org/entity/>
PREFIX wikibase: <http://wikiba.se/ontology#>
PREFIX p: <http://www.wikidata.org/prop/>
PREFIX v: <http://www.wikidata.org/prop/statement/>
PREFIX wdt: <http://www.wikidata.org/prop/direct/>
PREFIX pq: <http://www.wikidata.org/prop/qualifier/>
SELECT DISTINCT ?s ?sp ?q ?sLabel ?spLabel ?qLabel WHERE {
?s p:P39 ?p .
?p v:P39 ?sp .
?p pq:P108 ?q .
SERVICE wikibase:label {
bd:serviceParam wikibase:language "en" .
}
}
This query returns all the positions held by that person. In my case, I want to limit myself to the held position of university teacher (wd:Q1622272).
If possible, I would ask for a simplified query.
Replace the variable ?sp with the specific position you want (i.e. wd:Q1622272) in the triple pattern ?p v:P39 ?sp .:
PREFIX bd: <http://www.bigdata.com/rdf#>
PREFIX wd: <http://www.wikidata.org/entity/>
PREFIX wikibase: <http://wikiba.se/ontology#>
PREFIX p: <http://www.wikidata.org/prop/>
PREFIX v: <http://www.wikidata.org/prop/statement/>
PREFIX wdt: <http://www.wikidata.org/prop/direct/>
PREFIX pq: <http://www.wikidata.org/prop/qualifier/>
SELECT DISTINCT ?s ?q ?sLabel ?qLabel WHERE {
?s p:P39 ?p .
?p v:P39 wd:Q1622272 . # Here
?p pq:P108 ?q .
SERVICE wikibase:label {
bd:serviceParam wikibase:language "en" .
}
}