如何优化我的递归 SPARQL 查询?
Posted
技术标签:
【中文标题】如何优化我的递归 SPARQL 查询?【英文标题】:How can I optimize my recursive SPARQL query? 【发布时间】:2021-10-20 15:12:43 【问题描述】:我正在尝试使用递归 SPARQL 查询从 Wikidata 中提取建筑物,但我不断收到查询超时。有没有办法绕过这个?
这是我当前的查询,选择所有具有 Freebase ID 或 Google Knowledge Graph ID 以及荷兰标签的建筑物:
SELECT DISTINCT ?building ?buildingLabel
WHERE
?building p:P2671|p:P646 ?id;
p:P31/ps:P31/wdt:P279* wd:Q41176;
rdfs:label ?buildingLabel .
FILTER(LANG(?buildingLabel) = 'nl') .
FILTER (?building != ?buildingLabel) .
我尝试手动查看几层深度,但由于某种原因,我没有得到三层或更多层深度的结果,即使它们确实存在。我已经尝试过使用:
SELECT ?building
WHERE
?building p:P31/ps:P31/wdt:P279 [p:P31/ps:P31/wdt:P279 [p:P31/ps:P31/wdt:P279 wd:Q41176]].
并使用
SELECT ?building
WHERE
?parent2 p:P31/ps:P31/wdt:P279 wd:Q41176.
?parent1 p:P31/ps:P31/wdt:P279 ?parent2.
?building p:P31/ps:P31/wdt:P279 ?parent1.
在 Wikidata 上有大约 224 万座建筑物和大约 1800 万个具有 Freebase ID 或 Google Knowledge Graph ID 的实体。我查看了this guide,但不太清楚如何将其应用于我的查询。我也阅读了this question 的答案,但不幸的是,使用多个查询对我来说并不是一个真正的选择。
【问题讨论】:
p:P31/ps:P31/wdt:P279 [p:P31/ps:P31/wdt:P279
不等于 p:P31/ps:P31/wdt:P279*
,因为 *
的优先级高于 /
- 如果您希望在层次结构中最多三个跃点,则应使用 p:P31/ps:P31/wdt:P279?/wdt:P279?/wdt:P279?
【参考方案1】:
如果您的意图是使用“递归”属性路径来查找建筑物类型的事物以及作为建筑物子类的类型,那么您使用 wdt:P279*
的第一个查询是正确的,而后面的尝试重复完整的 p:P31/ps:P31/wdt:P279
模式将无法匹配任何数据。
通过稍微简化第一个查询,我能够让它运行(在 39 秒内返回 96,297 个结果):
SELECT DISTINCT ?building ?buildingLabel
WHERE
?building p:P2671|p:P646 ?id;
wdt:P31/wdt:P279* wd:Q41176 .
?building rdfs:label ?buildingLabel .
FILTER(LANGMATCHES(LANG(?buildingLabel), "nl"))
两个显着变化:
p:P31/ps:P31
被 wdt:P31
替换,从查询中删除一个连接。
第二个FILTER
是不必要的,因为?building
(一个URI)和?buildingLabel
(一个字符串)必然是不相等的
【讨论】:
以上是关于如何优化我的递归 SPARQL 查询?的主要内容,如果未能解决你的问题,请参考以下文章