首页 > 解决方案 > 查询以获取某个实体类的数量属性

问题描述

我要做的是获取具有特定类别的数量属性类型的属性(例如城市、国家、人类、河流、地区、山等)。我尝试了几个像 Country ( wd:Q6256) 这样的类,在下面的查询中可以正常工作,但是许多其他类使查询超过了时间限制。我怎样才能达到优化下面查询的结果?或者有没有其他方法可以在某个类中获取 Quantity 类型的属性?

SELECT DISTINCT ?p_ ?pLabel ?pAltLabel
WHERE {
  VALUES (?class) {(wd:Q515)}
  ?x ?p_ [].
  ?x p:P31/ps:P31 ?class.

  ?p wikibase:claim ?p_.
  ?p wikibase:directClaim ?pwdt.
  ?p wikibase:propertyType ?pType.
  FILTER (?pType = wikibase:Quantity)
  SERVICE wikibase:label { bd:serviceParam wikibase:language "ko,en". }
}

标签: sparqlwikidata

解决方案


尝试1:优化查询

一些观察:

  • 而不是p:P31/ps:P31,您可以wdt:P31通过避免两个属性跳跃来使用 which 更快,但只找到真实的陈述
  • 昂贵的部分是最后对标签服务的调用,可以通过在行首注释掉该行来看#
  • 该查询检索每个城市的每个声明(很多!),获取声明的属性(很少!),最后只删除重复项(使用DISTINCT
  • 因此,同一属性会多次调用标签服务,每次声明一次!这是查询的大问题
  • 这可以通过将属性的检索移动DISTINCT到子查询中来避免,并且只在少数属性的末尾调用标签服务
  • 在那次更改之后,它应该很快,但仍然很慢,因为查询优化器似乎以错误的顺序评估查询。按照此页面的提示,我们可以关闭查询优化器。

这对我有用:

SELECT ?p ?pLabel ?pAltLabel {
  hint:Query hint:optimizer "None" .
  {
    SELECT DISTINCT ?p_ {
      VALUES ?class { wd:Q515 }
      ?x wdt:P31 ?class.
      ?x ?p_ [].
    }
  }
  ?p wikibase:claim ?p_.
  ?p wikibase:propertyType ?pType.
  FILTER (?pType = wikibase:Quantity)
  SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}

尝试 2:将任务拆分为多个查询

在了解到上述方法不适用于某些最大的类别(例如wd:Q5“人类”)后,我尝试了另一种方法。这将获得所有结果,但不是在单个查询中。它需要发送约 25 个单独的查询并在之后组合结果:

  • 我们首先列出数量属性。截至今天,其中有 503 个。
  • 我们只想保留那些实际用于“人类”类型的项目的属性。
  • 因为该检查非常慢(它需要查看数百万个项目),所以我们首先只检查列表中的前 20 个属性。
  • 在第二个查询中,我们将检查接下来的 20 个,依此类推。

这是测试前 20 个属性的查询:

SELECT DISTINCT ?p ?pLabel ?pAltLabel {
  hint:Query hint:optimizer "None" .
  {
    SELECT ?p ?pLabel ?pAltLabel {
      ?p wikibase:propertyType wikibase:Quantity.
      SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
    }
    OFFSET 0 LIMIT 20
  }
  ?p wikibase:claim ?p_.
  ?x ?p_ [].
  ?x wdt:P31 wd:Q5.
}

将其OFFSET增加到 20、40、60 等等,最多 500,以测试所有属性。


推荐阅读