【问题标题】:Get highest level P131 for given place on Wikidata在 Wikidata 上获取给定位置的最高级别 P131
【发布时间】:2021-05-06 11:31:56
【问题描述】:

我有以下疑问:

SELECT DISTINCT
?place
?place_eng
?admin_eng
?country_eng
WHERE {
  VALUES ?place { wd:Q3437 wd:Q1903 wd:Q5083 }
  ?place wdt:P131 ?admin.
  ?place wdt:P17 ?country.
  SERVICE wikibase:label {
    bd:serviceParam wikibase:language "en,en".
    ?place rdfs:label ?place_eng.
    ?admin rdfs:label ?admin_eng.
    ?country rdfs:label ?country_eng.
  }
}

这会产生数据:

place place_eng admin_eng country_eng
wd:Q1903 Catania Metropolitan City of Catania Italy
wd:Q3437 Perugia Province of Perugia Italy
wd:Q5083 Seattle King County United States of America

正如您在admin_eng 下看到的,这包括城市所在的第一个行政区域,通过该地点的 P131(位于行政区域实体中)财产。

而不是它,我想获得该地点所在的最高级别行政区域,例如美国城市的州或意大利城市的地区。例如:

place place_eng admin_eng country_eng
wd:Q1903 Catania Sicily Italy
wd:Q3437 Perugia Umbria Italy
wd:Q5083 Seattle Washington United States of America

我知道我需要沿着 P131 的链向上执行此操作,但我不知道如何告诉查询在下一级是国家本身时停止,或者如何在所有,真的。我几乎是 SPARQL 和 Wikidata 的初学者。

我还需要尽可能高效的解决方案,因为我需要在许多记录上运行它,但有效的解决方案是一个好的开始。

【问题讨论】:

  • SELECT DISTINCT ?place ?place_eng ?admin_eng ?country_eng WHERE { VALUES ?place { wd:Q3437 wd:Q1903 wd:Q5083 } ?place wdt:P131+ ?admin. ?admin wdt:P131 ?country . ?place wdt:P17 ?country. SERVICE wikibase:label { bd:serviceParam wikibase:language "en,en". ?place rdfs:label ?place_eng. ?admin rdfs:label ?admin_eng. ?country rdfs:label ?country_eng. } }
  • 我认为这个问题是你需要在数据中至少有两个 wdt:P131 实例才能工作。对于像瓦杜兹 (wd:Q1844) 这样的小国家的城市来说,情况并非如此。现在我在下面的回答也不适用于瓦杜兹,但那是因为列支敦士登被列为德意志联邦,它不再属于,所以数据问题可能会在适当的时候得到解决。

标签: sparql wikidata data-collection


【解决方案1】:

这个查询对我来说似乎工作得很好: 编辑答案:

SELECT DISTINCT
?place
?place_eng
?admin_eng
?country_eng
WHERE {
  VALUES ?place { wd:Q3437 }
  ?place wdt:P131+ ?admin .
  
  ?admin wdt:P131 ?country ;
         wdt:P17 ?country .
  
  SERVICE wikibase:label {
    bd:serviceParam wikibase:language "en".
    ?place rdfs:label ?place_eng.
    ?admin rdfs:label ?admin_eng.
    ?country rdfs:label ?country_eng.
  }
}

注意wdt:P131+:这意味着应该出现一个或多个该属性的实例。然后我们确保将?admin 和?country 与两个不同的边连接起来,wdt:P17 即“有国家”和wdt:P131,即“有行政单位”。 这可以确保?admin 直接位于?country 之下,并且?country 确实是一个国家/地区。

【讨论】:

  • 有趣;这似乎是一个很好的技巧。但我实际上对国家内部的一级管理很感兴趣,例如意大利地区。有没有办法修改该过滤器以停止一个级别,而不是在顶部(国家)级别?
  • 所以这个查询有效,它只是确保您选择的管理员直接在其国家之下。性能很差,所以我不得不将其限制为一个值 1:w.wiki/3Hiz
  • 谢谢。如果您编辑答案以包含此查询(或添加新答案),我会将其标记为已接受。你能解释一下分号行发生了什么吗?我不太明白那里的语法。
  • 是的,当然。分号表示您保持相同的主题,即?s ?p1 ?o1 ; ?p2 ?o2?s ?p1 ?o1 . ?s ?p2 ?o2 完全相同。我也会把这个放在我的答案中
  • 但是,如果您或其他人可以改进查询以提高性能,我将不胜感激,希望这是可能的。似乎只有 100 个值会超时,而我的(可悲的是不正确的)初始查询可以处理 5000 个。我需要在总共超过 200k 的值上运行它...... :(
【解决方案2】:

我找到了一个不需要任何回溯的解决方案:

SELECT DISTINCT ?start ?admin
WHERE {
  VALUES ?start { wd:Q3437 wd:Q1903 wd:Q5083 }
  ?start wdt:P131+ ?admin.
  ?admin wdt:P131 ?temp.
  ?temp wdt:P31 wd:Q6256.
}

这会从给定值开始选择不同的结果,递归地查看每个行政部门所属的链条(因此,一直到国家),然后选择那些自己拥有行政部门的行政部门 (?temp) ,它必须是国家的一个实例(因此它们必须是一级行政单位)。

以下也可以,但会向后遍历链:

SELECT DISTINCT ?start ?admin
WHERE {
  VALUES ?start { wd:Q3437 wd:Q1903 wd:Q5083 }
  ?start wdt:P131+ ?admin.
  ?temp ^wdt:P131 ?admin;
         wdt:P31 wd:Q6256.
}

我无法判断它是否会比其他版本更慢、更快或等效。如果有人知道,请发表评论。

【讨论】:

    猜你喜欢
    • 2021-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多