SPARQL queries doesn't works without LIMIT clause

吃可爱长大的小学妹 提交于 2019-12-11 01:28:06

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!