I'm trying to fetch French communes from Wikidata using SPARQL.
I want to also retrieve the departement code and the region code of the commune.
For now I have this query :
SELECT ?inseeCode ?commune ?nom ?dateFinNom ?dateFinCodeInsee ?adminEntityInseeCode
WHERE {
?commune p:P374 ?inseeStmt .
?inseeStmt ps:P374 ?inseeCode .
OPTIONAL {?inseeStmt pq:P582 ?dateFinCodeInsee .}
?commune wdt:P31 wd:Q484170 .
?commune p:P1448 ?nomStmt .
OPTIONAL {?nomStmt ps:P1448 ?nom .}
OPTIONAL {?nomStmt pq:P582 ?dateFinNom .}
?commune p:P131 ?adminEntitiesStmt .
?adminEntitiesStmt ps:P2586 ?adminEntityInseeCode .
}
LIMIT 100
The problem is the line ?adminEntitiesStmt ps:P2586 ?adminEntityInseeCode . which make return 0 results whereas I expect for each commune to retrieve all administrative entities codes (region, departement, etc.).
What did I do wrong?
You have to use the wdt: prefix (or concatenate p: and ps:) for directly accessing the object of a statement.
SELECT ?inseeCode ?commune ?nom ?dateFinNom ?dateFinCodeInsee ?adminEntityInseeCode
WHERE {
?commune p:P374 ?inseeStmt .
?inseeStmt ps:P374 ?inseeCode .
OPTIONAL {?inseeStmt pq:P582 ?dateFinCodeInsee .}
?commune wdt:P31 wd:Q484170 .
?commune p:P1448 ?nomStmt .
OPTIONAL {?nomStmt ps:P1448 ?nom .}
OPTIONAL {?nomStmt pq:P582 ?dateFinNom .}
?commune wdt:P131 ?adminEntitiesStmt .
?adminEntitiesStmt wdt:P2586 ?adminEntityInseeCode .
}
LIMIT 100
wdt:P2586 is similar to p:P2586/ps:P2586, but not exactly equivalent. For example, the first one automatically selects the best statements, while the latter considers all the statements (also the ones marked as deprecated).
Related
I want to load the following data of specific humans with the Wikidata Query Service:
properties
birth date
lifestyles
qualifiers
start times of the lifestyles
end times of the lifestyles
And I want exactly one row for each human in the output, no matter if no properties/qualifiers or multiple properties/qualifiers are set.
I managed to create a query which works with humans who have at least one lifestyle, but when there's none, the query takes a long time and instead of empty cells many lifestyles, start and end times are loaded which are not related to the human.
This is the query for the humans Q185140, Q463434 and Q3378937 and Q3378937 doesn't have a lifestyle, but still the lifestyles, lifestylesStarts and lifestylesEnds cells aren't empty as expected and instead full of values:
SELECT ?human ?humanLabel
(GROUP_CONCAT(DISTINCT ?lifestyleLabel;separator="|") AS ?lifestyles)
(GROUP_CONCAT(DISTINCT ?lifestyleStart;separator="|") AS ?lifestylesStarts)
(GROUP_CONCAT(DISTINCT ?lifestyleEnd;separator="|") AS ?lifestylesEnds)
(GROUP_CONCAT(DISTINCT ?dateBirth;separator="|") AS ?dateBirths)
WHERE {
VALUES ?human { wd:Q185140 wd:Q463434 wd:Q3378937 } .
OPTIONAL{ ?human p:P1576 ?statement . }
OPTIONAL{ ?statement ps:P1576 ?lifestyle . }
OPTIONAL{ ?statement pq:P580 ?lifestyleStart . }
OPTIONAL{ ?statement pq:P582 ?lifestyleEnd . }
OPTIONAL{ ?human wdt:P569 ?dateBirth . }
SERVICE wikibase:label {
bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en" .
?human rdfs:label ?humanLabel .
?lifestyle rdfs:label ?lifestyleLabel .
}
}
GROUP BY ?human ?humanLabel
You can run the query and see the output here.
What do I have to change to get empty cells if properties/qualifiers are not set?
I want to retrieve all distinct object properties of instances with the same type (class), starting with two initial seeds (wd:Q963 and wd:Q42320). First, I ask for the type (and maybe subtype) of such seeds. Second, all instances of the same class of the seeds are retrieved. Third, properties of the instances are retrieved. Finally, I want to retrieve descriptions of such properties and if possible alternative labels. My query is as follows:
select distinct ?property ?description ?label where{
{
wd:Q963 wdt:P31 ?typesSubject .
?instancesS (wdt:P31|wdt:P279) ?typesSubject .
?instancesS ?property ?unknown .
}
UNION
{
wd:Q42320 wdt:P31 ?typesObject .
?instancesO (wdt:P31|wdt:P279) ?typesObject .
?unknown ?property ?instancesO .
}
?claimPredicate wikibase:directClaim ?property .
?claimPredicate schema:description ?description .
?claimPredicate rdfs:label ?label .
FILTER(strstarts(str(?property),str(wdt:)))
FILTER(strstarts(str(?unknown),str(wd:)))
FILTER(LANG(?description) = "en").
FILTER(LANG(?label) = "en").
}
The problem is that my actual query takes a lot of time and it fails in the public Wikidata endpoint. Does anyone can provide me some hints to optimize such a query?
To be honest, I can't understand the aim of your query. I suppose you are interested in semantic similarity or something like.
Basically, you could reduce the number of joins, retrieving only unique wdt-predicates with nested SELECT DITINCT.
SELECT ?property ?claimPredicateLabel ?claimPredicateDescription
WHERE {
hint:Query hint:optimizer "None" .
{
SELECT DISTINCT ?property {
VALUES (?s) {(wd:Q963) (wd:Q42320)}
?s wdt:P31/^(wdt:P31|wdt:P279) ?instances .
?instances ?property ?unknown .
}
}
?claimPredicate wikibase:directClaim ?property .
SERVICE wikibase:label { bd:serviceParam wikibase:language "en" . }
}
Try it!
This is fast enough (~ 3s) even with SERVICE wikibase:label.
Also, you don't need FILTER(strstarts(str(?property),str(wdt:))) after ?claimPredicate wikibase:directClaim ?property.
As for hint:Query hint:optimizer "None", this hint forces Blazegraph to follow standard bottom-up evaluation order. In this particular query, hint:Query hint:optimizer "Runtime" or hint:SubQuery hint:runOnce true should also work.
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")
}
In the examples of the SPARQL of Wikidata, we have this one:
SELECT ?h ?date
WHERE
{
?h wdt:P31 wd:Q5 .
?h wdt:P569 ?date .
OPTIONAL {?h wdt:P570 ?d }
FILTER (?date > "1880-01-01T00:00:00Z"^^xsd:dateTime)
FILTER (!bound(?d))
}
LIMIT 1000
I understand that if you put Label after the name of a variable it shows the label. So, I don't understand why this shows no output:
SELECT ?h ?hLabel ?date ...
Thank you in advance!
I am not aware of that specific feature for Label after the variable name.
However, for rdfs:label, you can to inculde the rdfs:label in your query. Add the following line: ?h rdfs:label ?hLabel.:
SELECT ?h ?hLabel ?date WHERE
{
?h wdt:P31 wd:Q5 .
?h wdt:P569 ?date .
?h rdfs:label ?hLabel.
OPTIONAL {?h wdt:P570 ?d }
FILTER (?date > "1880-01-01T00:00:00Z"^^xsd:dateTime)
FILTER (!bound(?d))
}
LIMIT 1000
If you want labels in a specific language, e.g. for English add FILTER (langMatches( lang(?hLabel), "EN" ) )
Here is a stackoverflow intersting answer about labels.
Using SPARQL, I am trying the get the list of all english novels and their properties.
I would also like to find if a movie was taken based on that novel and get the movie name and its director, If a movie relationship exists.
Code:
SELECT ?movie ?director ?book ?author ?publisher ?illustrator
WHERE {
?movie dcterms:subject <http://dbpedia.org/resource/Category:films> ;
dbpedia-owl:basedOn ?book .
?movie dbp:director ?director .
?book a dbpedia-owl:Book .
?book dbp:author ?author .
?book dbp:publisher ?publisher .
?book dbp:illustrator ?illustrator .
}
limit 200
You can get a lot of correct results, if you modify your query like this...
PREFIX dcterms: <http://purl.org/dc/terms/>
PREFIX dbpedia-owl: <http://dbpedia.org/ontology/>
PREFIX dbp: <http://dbpedia.org/property/>
SELECT ?book ?author ?movie ?director ?publisher ?illustrator
WHERE {
?book a dbpedia-owl:Book .
OPTIONAL {?book dbp:author ?author .}
OPTIONAL {?book dbp:publisher ?publisher .}
OPTIONAL {?book dbp:illustrator ?illustrator .}
OPTIONAL {?book ^dbpedia-owl:basedOn ?movie . ?movie a dbpedia-owl:Film }
OPTIONAL {?movie dbp:director ?director .}
}
LIMIT 200
...but keep in mind that there are many movies that are not classified as dbpedia-owl:Film. Then of course you make a union with a few other popular classifications but that would still not guarantee there there won't be a movie based on a book, which will not be omitted.
And by the way what do you call "English novels" -- those written originally in English or those by English authors?