我有一个正在运行的Wikibase实例。我能够用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”的情况下也可以工作。但是似乎没有它,就会发生某种交叉联接/笛卡尔积,并且匹配的每个项都会重复总次数(n * n)。查询的哪一部分导致了此?
答案 0 :(得分:1)
执行联合查询,您的本地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“忘记”将?itemLabel
的本地绑定传递到VALUES
中-可能是因为?itemLabel
不在远程三重模式中出现-但“认为”它们通过了。
此错误会引起您两个问题:
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))
。
另请参见
Federated Query(Blazegraph Wiki)
Speed up federated query(关于SO的问题)