Wikidata SPARQL returns 结果太多

Wikidata SPARQL returns too many results

这是可以在 https://query.wikidata.org 中执行的查询,我应该只得到 17 个值,但它 returns 有 289 个结果 (17 * 17 = 289)。 我想用它的单位得到 属性 值。我指定 wdt:P2573 只是为了演示这个问题,在实际应用中 属性 是一个变量 ?p.

PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>

SELECT * WHERE {
  wd:Q2 wdt:P2573 ?o.
  wd:Q2 rdfs:label ?entName.
  ?realAtt wikibase:directClaim wdt:P2573.
  ?realAtt rdfs:label ?attName.
  ?realAtt wikibase:propertyType ?wdDataType.

  OPTIONAL {
    ?realAtt wikibase:statementValue ?psv.
    ?realAtt wikibase:claim ?pp.
    wd:Q2 ?pp ?quantityNode.
    ?quantityNode ?psv ?wdv.
    ?wdv wikibase:quantityUnit ?unit.
    ?wdv wikibase:quantityAmount ?qAmount.
    BIND(?qAmount AS ?val)
  }
  BIND(COALESCE(?val, ?o) AS ?val)


  BIND(COALESCE(?unit, "") AS ?unit)
  FILTER(((LANG(?o)) = "en") || ((LANG(?o)) = "") || (!ISLITERAL(?o)))
  FILTER(((LANG(?attName)) = "en") || ((LANG(?attName)) = ""))
  FILTER(((LANG(?entName)) = "en") || ((LANG(?entName)) = ""))
}

真实陈述的简单值不会与值节点自动连接(class diagram).

您的 MCVE 应该如下所示:

SELECT * WHERE {
  wd:Q2 wdt:P2573 ?o.
  OPTIONAL {
    wd:Q2 p:P2573/psv:P2573 ?wdv.
    ?wdv wikibase:quantityUnit ?unit.
    ?wdv wikibase:quantityAmount ?qAmount.
    # FILTER( ?unit != wd:Q199 )
  }
}

Try it!

在上面的查询中,?o?wdv 的唯一连接条件是它们与 wd:Q2 的相关性。
因此,您获得了 ?o?wdv 绑定的笛卡尔积(右,17×17 = 289)。

正确的查询应该是这样的:

SELECT * WHERE {
  wd:Q2 p:P2573/psv:P2573 ?wdv.
  OPTIONAL {
    ?wdv wikibase:quantityUnit ?unit.
    ?wdv wikibase:quantityAmount ?qAmount.
  }
}

Try it!

更新

以上查询仅适用于 quantities。显然,它不适用于时间或地球坐标。此外,有时语句根本没有完整的值。例如,带有字符串对象的语句只有简单的值。应该从语句中获取简单值,然后尝试从完整值中获取附加信息:

SELECT * {
  VALUES (?wd) {(wd:P2067)(wd:P1332)(wd:P1814)}
  ?wd wikibase:claim ?p;
      wikibase:statementProperty ?ps;
      wikibase:statementValue ?psv.
  wd:Q2 ?p ?wds.
  ?wds ?ps ?sv.
  OPTIONAL {
    ?wds ?psv ?wdv
    OPTIONAL {?wdv wikibase:quantityUnit ?unit.
    ?wdv wikibase:quantityAmount ?amount}
  }
}

Try it!

总的来说,语句的特征可以是多种多样的。用 table 格式表示所有这些数据不是很方便。这就是 RDF 存在的原因之一。