【问题标题】:How to get all properties for only a specific category in Wikidata?如何仅获取 Wikidata 中特定类别的所有属性?
【发布时间】:2018-04-16 16:39:11
【问题描述】:

是否有一种 RDF 数据/其他格式允许我获取一个类别中可能存在的所有属性,例如人,那么我应该返回诸如性别,出生日期之类的属性。

如何在https://query.wikidata.org/查询此信息?

我想要的是这个https://www.wikidata.org/wiki/Wikidata:List_of_properties/Summary_table 但是有没有更好的格式呢?我想以编程方式访问。

更新

这个查询太重了,导致超时。

SELECT ?p ?attName  WHERE {
          ?q wdt:P31 wd:Q5.
          ?q ?p ?statement.
          ?realAtt wikibase:claim ?p.
          ?realAtt rdfs:label ?attName.
          FILTER(((LANG(?attName)) = "en") || ((LANG(?attName)) = ""))
    }
    GROUP BY ?p ?attName

我必须指定实体,例如对 Barrack Obama 来说它可以工作,但这并没有给我所有可能的属性。

SELECT ?p ?attName  WHERE {
      BIND(wd:Q76 AS ?q)
      ?q wdt:P31 wd:Q5.
      ?q ?p ?statement.
      ?realAtt wikibase:claim ?p.
      ?realAtt rdfs:label ?attName.
      FILTER(((LANG(?attName)) = "en") || ((LANG(?attName)) = ""))
}
GROUP BY ?p ?attName

【问题讨论】:

  • 为什么不能使用像 SELECT DISTINCT ?p {?s rdf:type/rdfs:subClassOf* <THE_PERSON_URI> ; ?p ?o } 这样的 SPARQL 查询?
  • @AKSW 嗨,我将其解释为 SELECT DISTINCT ?p {?s wdt:P31 wd:Q5 ; ?p ?o } 任何人类实例的实际示例,但该查询非常耗费资源,导致“达到查询超时限制”,因为它正在获取人类的所有实例。
  • 我知道这个查询很昂贵。另一种虽然不完整的方法是 a) 将其简化为一些较小的子类(如果可能的话)或 b) 检查域为 person(或其子类之一)的属性
  • a) 不可能,因为人类是足够的子类。 b)它可能适用于人员类别,但不适用于其他类别,如行星,它具有来自许多不同属性类别的数据。所以丢失了很多信息。我认为我的临时解决方案是指定一个特定实例(我更新问题的最后一个查询)
  • 好吧,您至少可以将其限制为 n 在子查询中获得的实例数。不过,这至少可以返回更多属性,但仍然不能保证完整性

标签: sparql wdqs


【解决方案1】:

1

您链接到的页面是由机器人创建的。如果您需要了解机器人的工作原理,请联系BetaBot 操作员。

2

也许机器人依赖于wd:P1963 属性:

SELECT ?property ?propertyLabel {
  VALUES (?class) {(wd:Q5)}
  ?class wdt:P1963 ?property
  SERVICE wikibase:label { bd:serviceParam wikibase:language "en" }   
} ORDER BY ASC(xsd:integer(strafter(str(?property), concat(str(wd:), "P"))))

以上查询returns49条结果。

3

我建议您依赖属性页中的类型约束

SELECT ?property ?propertyLabel {
  VALUES (?class) {(wd:Q5)}
  ?property a wikibase:Property .
  ?property p:P2302 [ ps:P2302 wd:Q21503250 ; 
                      pq:P2309 wd:Q21503252 ; 
                      pq:P2308 ?class ] .
  SERVICE wikibase:label { bd:serviceParam wikibase:language "en" }   
} ORDER BY ASC(xsd:integer(strafter(str(?property), concat(str(wd:), "P"))))

以上查询returns700条结果。

4

您问题的第一个查询适用于相对较小的类,例如。 G。 wd:Q6256(“国家”)。在公共端点上,无法使查询适用于大型类。

但是,您可以将查询拆分为小部分。在 Python 中:

from wdqs import Client
from time import sleep

client = Client()
result = client.query("SELECT (count(?p) AS ?c) {?p a wikibase:Property}")

count = int(result[0]["c"])
offset = 0
limit = 50
possible = []

while offset <= count:
    props = client.query("""
        SELECT ?property  WHERE { 
            hint:Query hint:optimizer "None" .
            {
              SELECT ?property {
                  ?property a wikibase:Property .
              } ORDER BY ?property OFFSET %s LIMIT %s
            }
            ?property wikibase:directClaim ?wdt.
            FILTER EXISTS {
                ?human ?wdt [] ; wdt:P31 wd:Q5 .
                hint:Group hint:maxParallel 501 .   
            }
            hint:Query hint:filterExists "SubQueryLimitOne" .
            # SERVICE wikibase:label { bd:serviceParam wikibase:language "en" }
        } 
        """ % (offset, limit))

    for prop in props:
        possible.append(prop['property'])
    offset += limit
    print (len(possible), min(offset, count))
    sleep(0.25)

输出is的最后一行:

2156 5154

【讨论】:

  • 嗨,谢谢,我试过了,“人类”类似乎还可以,但对于其他类,我失去了一些财产,仍然像 Q43229(组织),它没有给我 P571(初始),此属性没有类型约束。
  • 嘿,非常感谢,很抱歉我这几天没有在这个网站上活跃。我稍后再看。谢谢
  • @William,好的。 wdqs 在这里:github.com/yuvipanda/python-wdqs。答案的先前版本包含使用 SPARQLWrapper 的代码。可能您可以使用并发请求:Wikidata allows 最多来自一个 IP 的 5 个并发请求。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多