比较联合查询中的标签

comparing labels in a federated query

我有一个 Wikibase 运行ning 实例。我能够 运行 成功地与 Wikidata 进行联合查询。我有一些比较标签的查询:

PREFIX xwdt: <http://www.wikidata.org/prop/direct/>
PREFIX xwd: <http://www.wikidata.org/entity/>
PREFIX xpq: <http://www.wikidata.org/prop/qualifier/>
PREFIX xps: <http://www.wikidata.org/prop/statement/>
PREFIX xp: <http://www.wikidata.org/prop/>

select ?item  ?wditem ?itemLabel ?wid ?wditemlabel
where {
  ?item wdt:P17 wd:Q39.
  ?item wdt:P31 wd:Q5.
  optional {
    ?item wdt:P14 ?wid .
  }
  ?item rdfs:label ?itemLabel.   
  SERVICE <https://query.wikidata.org/sparql> {
    ?wditem xwdt:P27 xwd:Q258.
    ?wditem xwdt:P106 xwd:Q937857.
    ?wditem rdfs:label ?wditemlabel.
    filter(LANGMATCHES(LANG(?wditemlabel), "en")).
  }
  filter(contains(?wditemlabel, ?itemLabel))
}
group by ?item ?itemLabel ?wid ?wditem ?wditemlabel

上面的方法可以通过标签匹配项目:

1) 我最初在 SERVICE 子句中有 filter(contains(?wditemlabel, ?itemLabel)),但它没有返回任何结果。但是,如果我对其中一个变量使用静态字符串(例如 filter(contains("test string", ?itemLabel))),它似乎可以工作。为什么它在比较一个变量和一个字符串而不是两个变量时有效?

2) 我希望查询在末尾没有 "group by" 的情况下也能正常工作。但看起来没有它,会出现某种交叉 join/Cartesian 产品,并且匹配的每个项目都会重复总次数 (n * n)。查询的哪一部分导致了这个?

执行联合查询,您的本地 Blazegraph 对 Wikidata 执行此类查询:

SELECT ?wditem ?wditemlabel
WHERE {
    ?wditem wdt:P27 wd:Q258.
    ?wditem wdt:P106 wd:Q937857.
    ?wditem rdfs:label ?wditemlabel.
    filter(LANGMATCHES(LANG(?wditemlabel), "en"))
    filter(contains(?wditemlabel, ?itemlabel))
}
VALUES () {
( ) ( ) ( ) ( ) ( )  ( ) ( ) ( ) ( ) ( )  ( ) ( ) ( ) ( ) ( )  ( ) ( ) ( ) ( ) ( )
( ) ( ) ( ) ( ) ( )  ( ) ( ) ( ) ( ) ( )  ( ) ( ) ( ) ( ) ( )  ( ) ( ) ( ) ( ) ( )
( ) ( ) ( ) ( ) ( )  ( ) ( ) ( ) ( ) ( )  ( ) ( ) ( ) ( ) ( )  ( ) ( ) ( ) ( ) ( )
( ) ( ) ( ) ( ) ( )  ( ) ( ) ( ) ( ) ( )  ( ) ( ) ( ) ( ) ( )  ( ) ( ) ( ) ( ) ( )
( ) ( ) ( ) ( ) ( )  ( ) ( ) ( ) ( ) ( )  ( ) ( ) ( ) ( ) ( )  ( ) ( ) ( ) ( ) ( )
} # 100 values

如您所见,Blazegraph "forgets" 将 ?itemLabel 的本地绑定传递给 VALUES — 可能是因为 ?itemLabel 不会出现在远程三重模式中 — 但 "thinks" 他们通过了。

这个错误会导致你的两个问题:

  1. Try the above query on Wikidata(0 个结果)
  2. Try the above query on Wikidata 没有 contains(82800 结果而不是 828)

解决方法

使用提示强制查询执行顺序:

select ?item ?wditem ?itemLabel ?wditemlabel
where {
  hint:Query hint:optimizer "None"
  SERVICE <https://query.wikidata.org/sparql> {
    ?wditem wdt:P27 wd:Q258.
    ?wditem wdt:P106 wd:Q937857.
    ?wditem rdfs:label ?wditemlabel.
    filter(lang(?wditemlabel)= "en").
  } 
  ?item wdt:P17 wd:Q39.
  ?item wdt:P31 wd:Q5.
  ?item rdfs:label ?itemLabel.
  filter(contains(?wditemlabel, ?itemLabel))
}

select ?item ?wditem ?itemLabel ?wditemlabel
where {
  ?item wdt:P17 wd:Q39.
  ?item wdt:P31 wd:Q5.
  ?item rdfs:label ?itemLabel.
  SERVICE <https://query.wikidata.org/sparql> {
    ?wditem wdt:P27 wd:Q258.
    ?wditem wdt:P106 wd:Q937857.
    ?wditem rdfs:label ?wditemlabel.
    filter(lang(?wditemlabel)= "en").
  }
  hint:Prior hint:runFirst true .
  filter(contains(?wditemlabel, ?itemLabel))
}

顺便说一下,您可以在原始查询中使用 DISTINCT 而不是 GROUP BY,或者使用额外的本地过滤,即。 e. filter(lang(?itemLabel)='ast').

比较

在 GraphDB 中,原始查询运行良好,但应将 contains(?wditemlabel, ?itemLabel) 替换为 contains(str(?wditemlabel), str(?itemLabel))

另见