问题
When I execute this sentence in the nobel prize database I got error when I avoid use LIMIT
clause.
The next query works, because it has the LIMIT
clause:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX nobel: <http://data.nobelprize.org/terms/>
PREFIX cat: <http://data.nobelprize.org/resource/category/>
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
PREFIX dbo: <http://dbpedia.org/ontology/>
PREFIX dbp: <http://dbpedia.org/property/>
PREFIX dbr: <http://dbpedia.org/resource/>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
SELECT DISTINCT ?parentName ?childName
WHERE {
?child owl:sameAs ?personChild ;
foaf:name ?childName .
SERVICE <http://dbpedia.org/sparql> {
{ ?personParent dbp:children ?personChild . }
UNION
{ ?personChild dbp:parents ?personParent . }
}
?parent owl:sameAs ?personParent ;
foaf:name ?parentName .
} LIMIT 2
It's bizarre because the same query doesn't works when I remove the LIMIT
clause and instead of the result I got the next error message:
Error 500: HTTP 400 error making the query: Bad Request
What is the reason of this behavior? Am I doing something wrong?
Thanks.
回答1:
I have loaded small part of triples from your Fuseki 1 into my Fuseki 2 and have analyzed network logs.
Executing your query, Fuseki (or rather ARQ) sends to DBpedia many queries of this kind (actually, prefixes are expanded):
SELECT *
WHERE
{ { ?personParent dbp:children viaf:58991016 }
UNION
{ viaf:58991016 dbp:parents ?personParent }
}
Suddenly, Fuseki sends this query:
SELECT *
WHERE
{ { ?personParent dbp:children <Barack Obama> }
UNION
{ <Barack Obama> dbp:parents ?personParent }
}
This strange URI in the query above is not valid. You can check this yourself, clicking "Barack Obama" on this page.
Virtuoso returns an error and Fuseki stops execution.
If the LIMIT
clause is not omitted, then, having some luck, Fuseki retrieves from DBpedia sufficient number of results (and stops execution without an error) before sending the erroneous above query.
I suggest to add some filtering conditions to your query:
PREFIX afn: <http://jena.hpl.hp.com/ARQ/function#>
SELECT DISTINCT ?parentName ?childName
WHERE {
?child owl:sameAs ?personChild ;
foaf:name ?childName .
FILTER (afn:namespace(?personChild) = str(dbpedia:))
SERVICE <http://dbpedia.org/sparql> {
{ ?personParent dbpprop:children ?personChild . }
UNION
{ ?personChild dbpprop:parents ?personParent . }
FILTER (isIRI(?personParent))
}
?parent owl:sameAs ?personParent ;
foaf:name ?parentName .
}
Run it!
The result should be:
+-------------------------------+----------------------+
| parentName | childName |
+-------------------------------+----------------------+
| "Marie Curie, née Sklodowska" | "Irène Joliot-Curie" |
| "Pierre Curie" | "Irène Joliot-Curie" |
| "Karl Manne Georg Siegbahn" | "Kai M. Siegbahn" |
+-------------------------------+----------------------+
In the query above:
PREFIX afn: <http://jena.hpl.hp.com/ARQ/function#>
—afn:
prefix declaration for Fuseki 1;FILTER (afn:namespace(?personChild) = str(dbpedia:))
— filters out incorrect URIs (and also non-DBpedia URIs, reducing the number of queries);FILTER (isIRI(?personParent))
— filters out occasional literal values of properties, reducing slightly DBpedia response size.
Now I understand, why you do not use DBpedia data about Nobel awards directly. The shortest path between Scylla of DBpedia data quality and Charybdis of Virtuoso 7 bugs seems to be the following:
SELECT DISTINCT ?dbpediaChild ?dbpediaParent {
VALUES (?award2) { (dbr:Nobel_Prize_in_Chemistry)
(dbr:Nobel_Prize_in_Physics)
(dbr:Nobel_Peace_Prize)
(dbr:Nobel_Prize_in_Physiology_or_Medicine)
(dbr:Nobel_Prize_in_Literature) }
VALUES (?award1) { (dbr:Nobel_Prize_in_Chemistry)
(dbr:Nobel_Prize_in_Physics)
(dbr:Nobel_Peace_Prize)
(dbr:Nobel_Prize_in_Physiology_or_Medicine)
(dbr:Nobel_Prize_in_Literature) }
?award1 a dbo:Award .
?award2 a dbo:Award .
?dbpediaChild dbo:award/(dbo:wikiPageRedirects*) ?award1 .
?dbpediaParent dbo:award/(dbo:wikiPageRedirects*) ?award2 .
?dbpediaChild dbp:parents|^dbp:children ?dbpediaParent .
}
Run it!
However, the result will be only:
+-------------------------+--------------------+
| dbpediaChild | dbpediaParent |
+-------------------------+--------------------+
| dbr:Kai_Siegbahn | dbr:Manne_Siegbahn |
| dbr:Irène_Joliot-Curie | dbr:Marie_Curie |
+-------------------------+--------------------+
来源:https://stackoverflow.com/questions/46821096/sparql-queries-doesnt-works-without-limit-clause