没有 LIMIT 子句,SPARQL 查询不起作用

SPARQL queries doesn't works without LIMIT clause

当我在 nobel prize database 中执行这句话时,当我避免使用 LIMIT 子句时出现错误。

下一个查询有效,因为它有 LIMIT 子句:

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

这很奇怪,因为当我删除 LIMIT 子句时相同的查询不起作用,而不是结果我得到了下一条错误消息:

错误 500:进行查询时出现 HTTP 400 错误:错误请求

这种行为的原因是什么?我做错了什么吗?

谢谢。

我已将您的 Fuseki 1 中的一小部分三元组加载到我的 Fuseki 2 中,并分析了网络日志。

执行您的查询,Fuseki(或更确切地说是 ARQ)向 DBpedia 发送许多此类查询(实际上,前缀被扩展):

SELECT  *
WHERE
  {   { ?personParent dbp:children  viaf:58991016 }
    UNION
      { viaf:58991016 dbp:parents  ?personParent }
  }

Fuseki 突然发送此查询:

SELECT  *
WHERE
  {   { ?personParent  dbp:children  <Barack Obama> }
    UNION
      { <Barack Obama>  dbp:parents  ?personParent }
  }

上面查询中的这个奇怪的 URI 无效。您可以自己检查一下,点击 this page 上的 "Barack Obama"。

Virtuoso returns 一个错误,Fuseki 停止执行。

如果没有省略 LIMIT 子句,那么,幸运的是,Fuseki 在发送上述错误查询之前从 DBpedia 检索了足够数量的结果(并停止执行而没有错误)。

我建议在您的查询中添加一些过滤条件:

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!

结果应该是:

+-------------------------------+----------------------+
|          parentName           |      childName       |
+-------------------------------+----------------------+
| "Marie Curie, née Sklodowska" | "Irène Joliot-Curie" |
| "Pierre Curie"                | "Irène Joliot-Curie" |
| "Karl Manne Georg Siegbahn"   | "Kai M. Siegbahn"    |
+-------------------------------+----------------------+

在上面的查询中:

  • PREFIX afn: <http://jena.hpl.hp.com/ARQ/function#> — Fuseki 1 的 afn: 前缀 declaration

  • FILTER (afn:namespace(?personChild) = str(dbpedia:)) — 过滤掉不正确的 URI(以及非 DBpedia URI,减少查询次数);

  • FILTER (isIRI(?personParent)) — 过滤掉偶尔出现的属性文字值,略微减少 DBpedia 响应大小。


现在我明白了,为什么不直接使用 DBpedia 的诺贝尔奖数据。 DBpedia 数据质量的 Scylla 和 Virtuoso 7 bug 的 Charybdis 之间的最短路径似乎如下:

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!

然而,结果只会是:

+-------------------------+--------------------+
|      dbpediaChild       |   dbpediaParent    |
+-------------------------+--------------------+
| dbr:Kai_Siegbahn        | dbr:Manne_Siegbahn |
| dbr:Irène_Joliot-Curie  | dbr:Marie_Curie    |
+-------------------------+--------------------+