I am trying to query wikidata to find musicians that share the same birthday, for example as in this snippet where these people share the same birthday (2nd April) and were born after 1900
PREFIX wikibase: <http://wikiba.se/ontology#>
PREFIX wdt: <http://www.wikidata.org/prop/direct/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
SELECT distinct ?name (year(?date) as ?year) WHERE {
?entityS wdt:P569 ?date .
?entityS wdt:P1477 ?name.
FILTER (datatype(?date) = xsd:dateTime)
FILTER (month(?date) = 4) # date
FILTER (day(?date) = 2) # month
FILTER (?date > "1900-01-01"^^xsd:dateTime)
}
(run)
I want to filter by occupation musician i.e. ?professions {wd:Q177220 wd:Q639669} however I am not having much success in applying this filter.
I have tried specifying VALUES ?professions {wd:Q177220 wd:Q639669}, to no effect.
SELECT distinct ?name (year(?date) as ?year) WHERE {
VALUES ?professions {wd:Q177220 wd:Q639669}
?entityS wdt:P569 ?date .
?entityS wdt:P1477 ?name.
?entityS wdt:P106 ?professions
FILTER (datatype(?date) = xsd:dateTime)
FILTER (month(?date) = 4) # date
FILTER (day(?date) = 2) # month
FILTER (?date > "1900-01-01"^^xsd:dateTime)
}
Related
I am trying to get actor names for a given film title (I also have the release date in hand) with my sparql query, but given the situation that multiple films have the same name, I'm trying to differentiate them with the release date. Some films don't have the release date specified, some films don't have the label specified.
I'm trying to get results when either the release date is specified and is matching, or when it is in the label of the film and is also matching.
If I can't match the date with one of these attributes, I want no results in return
Here is my current query:
PREFIX dbo: <http://dbpedia.org/ontology/>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT DISTINCT ?film ?aname
WHERE {
?film a dbo:Film ;
foaf:name "A Nightmare on Elm Street"#en ;
dbo:starring ?a .
?a foaf:name ?aname
OPTIONAL
{ ?film dbo:releaseDate ?rd
BIND(year(xsd:date(?rd)) AS ?rrd)
FILTER ( ( ?rd = "1984-04-30"^^xsd:date ) || ( ?rrd = 1984) )
}
OPTIONAL
{ ?film rdfs:label ?lab
FILTER regex(?lab, "1984", "i")
FILTER ( lang(?lab) = "en" )
}
}
I think you are misusing OPTIONAL here. Instead you should be looking at UNION.
What's the difference?
SELECT ?person ?child
WHERE {
?person a :Person .
OPTIONAL {?person :hasSon ?child}
OPTIONAL {?person :hasDaughter ?child}
}
Will return every person, and optionally their sons/daughters. However this will return also people without any children at all.
Instead, something like:
SELECT ?person ?child
WHERE {
?person a :Person .
{?person :hasSon ?child}
UNION
{?person :hasDaughter ?child}
}
Will only return people who have at least one son or daughter.
Now, in your example, I have a query working like this:
PREFIX dbo: <http://dbpedia.org/ontology/>
PREFIX dbp: <http://dbpedia.org/property/>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT DISTINCT ?film ?aname
WHERE {
?film a dbo:Film ;
foaf:name "A Nightmare on Elm Street"#en ;
dbo:starring ?a .
?a foaf:name ?aname
{ ?film dbp:released 1984}
UNION
{ ?film rdfs:label ?lab
FILTER regex(?lab, "1984", "i")
FILTER ( lang(?lab) = "en" )
}
}
Notice that I used the dbp:released property which seems to be working.
It seems that the property used for releases is inconsistent across films, i.e. some use dbp:released , others dbo:releaseDate.
If that's an issue, you can of course add another UNION statement in the query to deal with the different case.
One more thing:
there are many triplestores out there that have reasoning, and reasoning is something that can help deal with a variety of such situations (disambiguation, multiple properties for the same thing, etc)
The query below is the accepted answer for my question Getting only english property value. When used on the Wikidata Query service try it! it will show shortNames for countries like Australia -> AUS and Austria -> AUT as requeted. Running the same query on my local Wikidata copy created a few weeks ago based on Apache Jena Fuseki the shortName column stays empty (see screenshot below).
What is the reason for the difference and how could the query be modified to also work with Apache Jena Fuseki?
# get a list countries with the corresponding ISO code
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX wd: <http://www.wikidata.org/entity/>
PREFIX wdt: <http://www.wikidata.org/prop/direct/>
PREFIX wikibase: <http://wikiba.se/ontology#>
PREFIX p: <http://www.wikidata.org/prop/>
PREFIX ps: <http://www.wikidata.org/prop/statement/>
PREFIX pq: <http://www.wikidata.org/prop/qualifier/>
SELECT ?country ?countryLabel ?shortName (MAX(?pop) as ?population) ?coord ?isocode
WHERE
{
# instance of country
?country wdt:P31 wd:Q3624078.
OPTIONAL {
?country rdfs:label ?countryLabel filter (lang(?countryLabel) = "en").
}
OPTIONAL {
?country p:P1813 ?shortNameStmt. # get the short name statement
?shortNameStmt ps:P1813 ?shortName # the the short name value from the statement
filter (lang(?shortName) = "en") # filter for English short names only
filter not exists {?shortNameStmt pq:P31 wd:Q28840786} # ignore flags (aka emojis)
}
OPTIONAL {
# get the population
# https://www.wikidata.org/wiki/Property:P1082
?country wdt:P1082 ?pop.
}
# get the iso countryCode
{ ?country wdt:P297 ?isocode }.
# get the coordinate
OPTIONAL { ?country wdt:P625 ?coord }.
}
GROUP BY ?country ?countryLabel ?shortName ?population ?coord ?isocode
ORDER BY ?countryLabel
#UninformedUser's test query:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX wd: <http://www.wikidata.org/entity/>
PREFIX wdt: <http://www.wikidata.org/prop/direct/>
PREFIX wikibase: <http://wikiba.se/ontology#>
PREFIX p: <http://www.wikidata.org/prop/>
PREFIX ps: <http://www.wikidata.org/prop/statement/>
PREFIX pq: <http://www.wikidata.org/prop/qualifier/>
SELECT ?country ?shortNameStmt ?shortName WHERE
{
VALUES ?country {wd:Q40} ?country wdt:P31 wd:Q3624078.
OPTIONAL {
?country p:P1813 ?shortNameStmt.
?shortNameStmt ps:P1813 ?shortName filter (lang(?shortName) = "en")
filter not exists {?shortNameStmt pq:P31 wd:Q28840786}
}
}
Did not give a result on the truthy-based import of wikidata while it worked on the latest-all import. The same holds true for the full query. Still it would be good to know why the query does not work with the truthy dataset.
In dbpedia I select some pages with label starting 'A'. Here I'm using additional filter by subject to narrow the set. In original version there are another conditions (result set is much bigger)
PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
PREFIX purl: <http://purl.org/dc/terms/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX : <http://dbpedia.org/page/>
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX dbr: <http://dbpedia.org/resource/>
SELECT DISTINCT
?pageType
WHERE
{
{
?page rdfs:label ?label .
?page a ?pageType .
?page <http://purl.org/dc/terms/subject> <http://dbpedia.org/resource/Category:Banking> .
}
FILTER ( strstarts(str(?pageType), 'http://dbpedia.org/ontology') )
}
LIMIT 1000
sparql results
Here I select only page types to be clear with rest of the question.
This is the whole set. Now I want to exclude some pages. Exclude all agents (persons, organization etc):
PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
PREFIX purl: <http://purl.org/dc/terms/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX : <http://dbpedia.org/page/>
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX dbr: <http://dbpedia.org/resource/>
SELECT DISTINCT
?pageType
WHERE
{
{
?page rdfs:label ?label .
?page a ?pageType .
?page <http://purl.org/dc/terms/subject> <http://dbpedia.org/resource/Category:Banking> .
MINUS { ?page a dbo:Agent }
}
FILTER ( strstarts(str(?pageType), 'http://dbpedia.org/ontology') )
}
LIMIT 1000
The result.
Ok. Then I want to exclude more types, for example Written_Work. I tried different approaches, but unabled to find the correct one.
This returns nothing:
WHERE
{
{
?page rdfs:label ?label .
?page a ?pageType .
?page <http://purl.org/dc/terms/subject> <http://dbpedia.org/resource/Category:Banking> .
MINUS { ?page a dbo:Agent }
MINUS { ?page a dbo:WrittenWork }
}
This is like no filter is set:
WHERE
{
{
?page rdfs:label ?label .
?page a ?pageType .
?page <http://purl.org/dc/terms/subject> <http://dbpedia.org/resource/Category:Banking> .
MINUS { ?page a dbo:Agent, dbo:WrittenWork }
}
The question is:
what way should I go to exclude pages of certain types (direct and superclass)?
It look's like this is working answer (how to exclude multiple of types)
{
?page purl:subject ?id .
?page a ?pageType .
FILTER NOT EXISTS {
?page a/rdfs:subClassOf* ?skipClasses .
FILTER(?skipClasses in (dbo:Agent, dbo:Place, dbo:Work))
}
}
In this example all dbo:Agents, db:Places, dbo:Works will be filtered out.
Given a list of Wikipedia article titles (people's names), how do I print the name, birthday pair for each person?
Here is one way to do it using the VALUES clause in SPARQL 1.1:
PREFIX dbpedia: <http://dbpedia.org/resource/>
PREFIX dbpedia-owl: <http://dbpedia.org/ontology/>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?givenName ?surname ?birth
WHERE
{
?person dbpedia-owl:birthDate ?birth .
?person foaf:givenName ?givenName .
?person foaf:surname ?surname .
VALUES ?person { dbpedia:Albert_Einstein dbpedia:Max_Planck dbpedia:Marie_Curie }
}
I am trying get the dbpedia movie link using the movie name in the first query and pass that link in the second query to get the movies similar to this movie.For e.g Lagaan.Now instead of passing the link manually in the second query is there a way to combine the two queries and pass the output of first query as an input to the second query.i.e:the link of the movie lagaan.Also,if the first query gives multiple links eg:if i am searching for Harry potter it will return multiple harry potter series links so,it should handle that case as well.
Query1
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
prefix dbpedia-owl: <http://dbpedia.org/ontology/>
select distinct ?film where {
?film a dbpedia-owl:Film .
?film rdfs:label ?label .
filter regex( str(?label), "Lagaan", "i")
}
limit 10
Query 2
PREFIX dbpedia-owl: <http://dbpedia.org/ontology/>
select ?similar (count(?p) as ?similarity) where {
values ?movie { <http://dbpedia.org/resource/Lagaan> }
?similar ?p ?o ; a dbpedia-owl:Film .
?movie ?p ?o .
}
group by ?similar ?movie
having count(?p) > 35
order by desc(?similarity)
Edited query:
select ?film ?similar (count(?p) as ?similarity) where {
{
select distinct ?film where {
?film a dbpedia-owl:Film .
?film rdfs:label ?label .
filter regex( str(?label), "Lagaan", "i")
}
}
?similar ?p ?o ; a dbpedia-owl:Film .
?film ?p ?o .
}
group by ?similar ?film
having count(?p) > 35
order by desc(?similarity)
corrected query as told by Joshua Taylor
select ?film ?other (count(*) as ?similarity) {
{
select ?film where {
?film a dbpedia-owl:Film ; rdfs:label ?label .
filter contains(lcase(?label),"lagaan")
}
limit 1
}
?film ?p ?o .
?other a dbpedia-owl:Film ; ?p ?o .
}
group by ?film ?other
having count(?p) > 25
order by desc(?similarity)
is there a way to combine the two queries and pass the output of first
query as an input to the second query.
SPARQL 1.1 defines subqueries. The results of inner queries are available to outer queries, so they are "passed" to them. In your case, you would have something along the lines of:
select ?similarMovie (... as ?similarity) where {
{ #-- QUERY 1, find one or more films
select distinct ?film where {
#-- ...
}
}
#-- QUERY 2, find films similar to ?film
#-- ...
}