如何使用SPARQL从Wikidata获取属性标签

时间:2019-06-07 01:21:39

标签: sparql wikidata sparqlwrapper

我正在使用SPARQLWrapper将SPARQL查询发送到Wikidata。 目前,我正在尝试查找实体的所有属性。例如。带有一个简单的元组,例如:wd:Q11663 ?a ?b.本身可以工作,但是我试图为返回的属性和实体找到人类可读的标签。

尽管SERVICE wikibase:label使用Wikidata的GUI界面,但不适用于SPARQLWrapper-SPARQLWrapper坚持为变量及其“标签”返回相同的值。

查询属性rdfs:label适用于实体(?b),但是此方法不适用于属性(?a)。

似乎该属性将作为完整的URI返回,例如http://www.wikidata.org/prop/direct/P1536。使用GUI,我可以成功查询wd:P1536 ?a ?b.。如果我将SPARQLWrapper作为第二个查询发送,但不能在第一个查询中发送,则可与SPARQLWrapper一起使用。

这是我的代码:

from SPARQLWrapper import SPARQLWrapper, JSON

sparql = SPARQLWrapper("http://query.wikidata.org/sparql")

sparql.setQuery("""
  SELECT ?a ?aLabel ?propLabel ?b ?bLabel
  WHERE
  {
    wd:Q11663 ?a ?b.

    # Doesn't work with SPARQLWrapper
    #SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
    #?prop wikibase:directClaim ?p

    # but this does (and is more portable)
    ?b rdfs:label ?bLabel. filter(lang(?bLabel) = "en").

    # doesn't work
    #?a rdfs:label ?aLabel. 

    # property code can be extracted successfully
    BIND(  strafter(str(?a), "prop/direct/") AS ?propLabel).
    #BIND( CONCAT("wd:", strafter(str(?a), "prop/direct/") ) AS ?propLabel).

    # No matches, even if I concat 'wd:' to ?propLabel
    ?propLabel rdfs:label ?aLabel
    # generic search for any properties also fails
    #?propLabel ?zz ?aLabel.
   }
 """)

# However, this returns a label for P1536 - which is one of wd:Q11663's properties
sparql.setQuery("""SELECT ?b WHERE
   {
      wd:P1536 rdfs:label ?b.
   }
""")

那么如何在一个查询中获取属性标签(应该更有效)?

[旁白:是的,我有点不熟悉,并且已经准备好使用EN过滤器-如果我什么都没拿回来,经常会把它丢弃]

1 个答案:

答案 0 :(得分:1)

我在两种方法上遇到问题-上面的代码包含两种方法的混合。另外,SPARQLWrapper在这里也不是问题。

使用Wikibase标签服务的第一种方法应如下:

SELECT ?a ?aLabel ?propLabel ?b ?bLabel
WHERE
{
  ?item rdfs:label "weather"@en.
  ?item ?a ?b.

  SERVICE wikibase:label { bd:serviceParam wikibase:language "en". } 
  ?prop wikibase:directClaim ?a .
}

此代码还包括从标签('weather')到查询实体(?item)的查找。

SERVICE正在运行,但是如果没有rdfs:label定义,则它仅返回实体。 GUI和SPARQLWrapper(到SPARQL端点)只是以不同的顺序返回结果-好像我看到了很多“失败”的输出(即,实体和失败的标签都被报告为相同)。

当我开始在下面的方法中添加一个OPTIONAL子句时,这一点变得很清楚。

?prop wikibase:directClaim ?a .行非常简单。 Wikibase定义了directClaim以将属性映射到实体。然后,这允许它定义有关属性(即标签)的元组。许多其他本体都使用相同的标识符。

我的第二个(更通用的方法)是您在许多书籍和在线教程中找到的方法。这里的问题是wikibase的属性中有完整的URL,我需要将它们转换为实体。我尝试了字符串操作,但这会产生字符串文字-不是实体。解决方案是再次使用directClaim

?prop wikibase:directClaim ?a .
?prop rdfs:label ?propLabel.  filter(lang(?propLabel) = "en").

请注意,只有定义了rdfs:label时,此方法才返回结果。即使未定义标签,添加OPTIONAL也会返回结果。