When I try to query what geographical areas two cities belong Wikidata SparQL query hangs. It works fine for each of the cites.
Any ideas what's going on and whether a workaround is needed?
# This works:
# select ?z ?i where {
# select ?z ?i where {
# values ?z { wd:Q936768 }
# ?z wdt:P131+ ?i.
# }
# }
# This hangs:
select ?z ?i where {
select ?z ?i where {
values ?z { wd:Q936768 wd:Q159288 }
?z wdt:P131+ ?i.
}
}
Related
Is there an RDF data/other format that allow me to get all the properties that can exist in a category e.g. Person, then I should be returned properties like sex, date of birth.
How to query this information at https://query.wikidata.org/ ?
What I want is this https://www.wikidata.org/wiki/Wikidata:List_of_properties/Summary_table
But is there a better format for this? I want to access programmatically.
UPDATE
This query is too heavy, causes timeout.
SELECT ?p ?attName WHERE {
?q wdt:P31 wd:Q5.
?q ?p ?statement.
?realAtt wikibase:claim ?p.
?realAtt rdfs:label ?attName.
FILTER(((LANG(?attName)) = "en") || ((LANG(?attName)) = ""))
}
GROUP BY ?p ?attName
I must specify the entity, e.g. to Barrack Obama then it works, but this does not give me the all possible properties.
SELECT ?p ?attName WHERE {
BIND(wd:Q76 AS ?q)
?q wdt:P31 wd:Q5.
?q ?p ?statement.
?realAtt wikibase:claim ?p.
?realAtt rdfs:label ?attName.
FILTER(((LANG(?attName)) = "en") || ((LANG(?attName)) = ""))
}
GROUP BY ?p ?attName
1
The page you have linked to is created by a bot. Contact the BetaBot operator, if you need to know how the bot works.
2
Perhaps the bot relies on the wd:P1963 property:
SELECT ?property ?propertyLabel {
VALUES (?class) {(wd:Q5)}
?class wdt:P1963 ?property
SERVICE wikibase:label { bd:serviceParam wikibase:language "en" }
} ORDER BY ASC(xsd:integer(strafter(str(?property), concat(str(wd:), "P"))))
The above query returns 49 results.
3
I'd suggest you rely on type constraints from property pages:
SELECT ?property ?propertyLabel {
VALUES (?class) {(wd:Q5)}
?property a wikibase:Property .
?property p:P2302 [ ps:P2302 wd:Q21503250 ;
pq:P2309 wd:Q21503252 ;
pq:P2308 ?class ] .
SERVICE wikibase:label { bd:serviceParam wikibase:language "en" }
} ORDER BY ASC(xsd:integer(strafter(str(?property), concat(str(wd:), "P"))))
The above query returns 700 results.
4
The first query from your question works fine for relatively small classes, e. g. wd:Q6256 ('country'). On the public endpoint, it is not possible to make the query work for large classes.
However, you could split the query into small parts. In Python:
from wdqs import Client
from time import sleep
client = Client()
result = client.query("SELECT (count(?p) AS ?c) {?p a wikibase:Property}")
count = int(result[0]["c"])
offset = 0
limit = 50
possible = []
while offset <= count:
props = client.query("""
SELECT ?property WHERE {
hint:Query hint:optimizer "None" .
{
SELECT ?property {
?property a wikibase:Property .
} ORDER BY ?property OFFSET %s LIMIT %s
}
?property wikibase:directClaim ?wdt.
FILTER EXISTS {
?human ?wdt [] ; wdt:P31 wd:Q5 .
hint:Group hint:maxParallel 501 .
}
hint:Query hint:filterExists "SubQueryLimitOne" .
# SERVICE wikibase:label { bd:serviceParam wikibase:language "en" }
}
""" % (offset, limit))
for prop in props:
possible.append(prop['property'])
offset += limit
print (len(possible), min(offset, count))
sleep(0.25)
The last line of the output is:
2156 5154
Is it possible to implement blank node skolemization in SPARQL without iteration? It seems to me that iteration is required to skolemize chains of blank nodes, such as:
#prefix : <http://example.com/> .
[ a :A ;
:p1 [
a :B
]
] .
A SPARQL Update operation for skolemization can start from the blank nodes that appear as subjects only in triples without blank node objects:
DELETE {
?b1 ?outP ?outO .
?inS ?inP ?b1 .
}
INSERT {
?iri ?outP ?outO .
?inS ?inP ?iri .
}
WHERE {
{
SELECT ?b1 (uuid() AS ?iri)
WHERE {
{
SELECT DISTINCT ?b1
WHERE {
?b1 ?p1 [] .
FILTER isBlank(?b1)
FILTER NOT EXISTS {
?b1 ?p2 ?b2 .
FILTER isBlank(?b2)
}
}
}
}
}
?b1 ?outP ?outO .
OPTIONAL {
?inS ?inP ?b1 .
}
}
This operation can be repeated until no blank nodes are found in the data:
ASK {
?bnode ?p [] .
FILTER isBlank(?bnode)
}
Is it possible to avoid the iteration and implement the blank node skolemization in a single SPARQL Update operation?
(Also, this approach assumes there are no "orphan" blank nodes (i.e. blank nodes that appear only as objects).)
I found a two-step solution skolemising subjects and objects separately and storing the blank node aliases (links between blank nodes and IRIs via owl:sameAs) as intermediate data:
PREFIX : <http://example.com/>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
####################
# Rewrite subjects #
####################
DELETE {
?bnode ?p ?o .
}
INSERT {
?iri ?p ?o .
GRAPH :aliases {
?bnode owl:sameAs ?iri .
}
}
WHERE {
{
SELECT ?bnode (uuid() AS ?iri)
WHERE {
{
SELECT DISTINCT ?bnode
WHERE {
?bnode ?p [] .
FILTER isBlank(?bnode)
}
}
}
}
?bnode ?p ?o .
}
;
###################
# Rewrite objects #
###################
DELETE {
?s ?p ?bnode .
}
INSERT {
?s ?p ?iri .
}
WHERE {
{
SELECT ?bnode ?iri
WHERE {
{
SELECT DISTINCT ?bnode
WHERE {
[] ?p ?bnode .
FILTER isBlank(?bnode)
}
}
OPTIONAL {
GRAPH :aliases {
?bnode owl:sameAs ?_iri .
}
}
BIND (coalesce(?_iri, uuid()) AS ?iri)
}
}
?s ?p ?bnode .
}
;
############################
# Clear blank node aliases #
############################
CLEAR GRAPH :aliases
I have a graph group <group> of m graphs <group_1>...<group_m> with n total triples. When I do a count together with a graph <graph> with k total triples outside of the graph group, I only get the number of triples n in the graph group:
select count(*)
from <group>
from <graph>
{?s ?p ?o}
Result: n
When I list the graphs in the graph group explicitly, however, I get the correct result:
select count(*)
from <group_1>
from <group_2>
...
from <group_m>
from <graph>
{?s ?p ?o}
Result: n + k
How can I obtain the correct result with the graph group and what is the reason for this behaviour?
You should use either two subqueries like this for example:
select ?n ?k (?n + ?k as ?totalCount) where {
{ select (count(*) as ?n) where {
graph group: { ?s ?p ?o } }
{ select (count(*) as ?k) where {
graph graph: { ?s ?p ?o } }
}
Or use a union:
select (count(?s1) as ?n)
(count(?s2) as ?k)
(?n + ?k as ?totalCount)
where {
{ graph group: { ?s1 ?p1 ?o1 } }
union
{ graph graph: { ?s2 ?p2 ?o2 } }
}
Have the following working SPARQL query that selects items from DBpedia that include the string "fish" in their name.
SELECT ?name, ?kingdom, ?phylum, ?class, ?order, ?family, ?genus, ?species, ?subspecies, ?img, ?abstract
WHERE {
?s dbpedia2:regnum ?hasValue;
rdfs:label ?name
FILTER regex( ?name, "fish", "i" )
FILTER ( langMatches( lang( ?name ), "EN" ))
?animal dbpedia2:name ?name;
foaf:depiction ?img;
dbpedia2:regnum ?kingdom
OPTIONAL { ?animal dbpedia2:ordo ?order . }
OPTIONAL { ?animal dbpedia2:phylum ?phylum . }
OPTIONAL { ?animal dbpedia2:classis ?class . }
OPTIONAL { ?animal dbpedia2:familia ?family . }
OPTIONAL { ?animal dbpedia2:genus ?genus . }
OPTIONAL { ?animal dbpedia2:species ?species . }
OPTIONAL { ?animal dbpedia2:subspecies ?subspecies . }
OPTIONAL {
FILTER ( langMatches( lang( ?abstract ), "EN" ))
}
}
GROUP BY ?name
LIMIT 500
Here is the result on SNORQL.
This approach finds animals with the word "fish" in their name (example: "starfish" which is not a fish but member of the phylum Echinoderm).
Would like a more precise query that selects DBpedia items by phylum, or by class, or by order, etc.
How to change the query to search only on dbpedia2:phylum (Chordata); on dbpedia2:classis (Actinopterygii); on dbpedia2:familia; etc. ?
Looking at Tuna, I see that there is a rdf:type assertion for the class
http://umbel.org/umbel/rc/Fish
that looks useful. E.g.,
select ?fish { ?fish a <http://umbel.org/umbel/rc/Fish> }
SPARQL results (10,000)
There's also the dbpedia-owl:Fish class, which gets more results:
select (count(*) as ?nFish) where {
?fish a dbpedia-owl:Fish .
}
SPARQL results (17,420)
While Wikipedia has lots of scientific classification information, I don't see much of it reflected in DBpedia. E.g,. while the Wikipedia article for Tuna has kingdom, phylum, class, order, etc., I don't see that data in the corresponding DBpedia resource.
Notes
Note that your query, as written, isn't actually legal SPARQL (even if Virtuoso, the SPARQL endpoint that DBpedia uses, accepts it). You can't have commas between the projection variables. Also, once you group by one variable, the non-group variables can't appear in the variable list. You could sample the other values though. E.g., you should end up with something like:
SELECT
?name
(sample(?kingdom) as ?kingdom_)
(sample(?phylum) as ?phylum_)
#-- ...
(sample(?img) as ?img_)
(sample(?abstract) as ?abstract_)
WHERE {
?s dbpedia2:regnum ?hasValue;
rdfs:label ?name
FILTER regex( ?name, "fish", "i" )
FILTER ( langMatches( lang( ?name ), "EN" ))
?animal dbpedia2:name ?name;
foaf:depiction ?img;
dbpedia2:regnum ?kingdom
OPTIONAL { ?animal dbpedia2:ordo ?order . }
OPTIONAL { ?animal dbpedia2:phylum ?phylum . }
OPTIONAL { ?animal dbpedia2:classis ?class . }
OPTIONAL { ?animal dbpedia2:familia ?family . }
OPTIONAL { ?animal dbpedia2:genus ?genus . }
OPTIONAL { ?animal dbpedia2:species ?species . }
OPTIONAL { ?animal dbpedia2:subspecies ?subspecies . }
OPTIONAL {
FILTER ( langMatches( lang( ?abstract ), "EN" ))
}
}
GROUP BY ?name
LIMIT 500
I have two SPARQL updates.First one:
INSERT
{ GRAPH <[http://example/bookStore2]> { ?book ?p ?v } }
WHERE
{ GRAPH <[http://example/bookStore]>
{ ?book dc:date ?date .
FILTER ( ?date > "1970-01-01T00:00:00-02:00"^^xsd:dateTime )
?book ?p ?v
} }
Second:
INSERT
{ GRAPH <[http://example/bookStore2]> { ?book ?p ?v } }
WHERE
{ GRAPH <[http://example/bookStore3]>
{ ?book dc:date ?date .
FILTER ( ?date > "1980-01-01T00:00:00-02:00"^^xsd:dateTime )
?book ?p ?v
} }
Can i combine them with the UNION operator? And if yes, is it an equivalent result? Is it possible to use UNION in SPARQL updates such as in "Select"?
AndyS's answer is correct; you can combine them, and the description of UNION is found in section 7 Matching Alternatives of the SPARQL specification. The combined query would be:
INSERT {
GRAPH <[http://example/bookStore2]> { ?book ?p ?v }
}
WHERE{
{
GRAPH <[http://example/bookStore]> {
?book dc:date ?date .
FILTER ( ?date > "1970-01-01T00:00:00-02:00"^^xsd:dateTime )
?book ?p ?v
}
}
UNION
{
GRAPH <[http://example/bookStore3]> {
?book dc:date ?date .
FILTER ( ?date > "1980-01-01T00:00:00-02:00"^^xsd:dateTime )
?book ?p ?v
}
}
}
In this particular case where the patterns are so similar, you could also just abstract out the differing parts with VALUES:
INSERT {
GRAPH <[http://example/bookStore2]> { ?book ?p ?v }
}
WHERE{
values (?graph ?startDate) {
(<[http://example/bookStore]> "1970-01-01T00:00:00-02:00"^^xsd:dateTime)
(<[http://example/bookStore3]> "1980-01-01T00:00:00-02:00"^^xsd:dateTime)
}
GRAPH ?graph {
?book dc:date ?date .
FILTER ( ?date > ?startDate )
?book ?p ?v
}
}
The WHERE clause is the same as SPARQL Query - you can use UNION.