如何使用 SPARQL 从维基数据中获取 属性 标签
How to get property labels from Wikidata using SPARQL
我正在使用 SPARQLWrapper 将 SPARQL 查询发送到维基数据。
目前我正在尝试查找实体的所有属性。例如。使用一个简单的元组,例如:wd:Q11663 ?a ?b.
这本身有效,但我试图为返回的属性和实体找到人类可读的标签。
虽然 SERVICE wikibase:label
使用 Wikidata 的 GUI 界面工作,但这不适用于 SPARQLWrapper - 它坚持为变量及其 'label'.
返回相同的值
查询 属性 rdfs:label
适用于实体 (?b),但此方法不适用于 属性 (?a)。
看起来 属性 作为完整的 URI 返回,例如 http://www.wikidata.org/prop/direct/P1536
。使用 GUI 我可以成功查询 wd:P1536 ?a ?b.
。如果我将它作为第二个查询发送,这适用于 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 过滤器 - 如果我没有得到任何回报,通常会放弃它]
我在使用两种方法时遇到了问题 - 上面的代码混合了这两种方法。此外,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
定义,那么它只是 return 实体。 GUI 和 SPARQLWrapper(到 SPARQL 端点)只是以不同的顺序 return 处理结果 - 所以看起来我看到了很多 'failed' 输出(即实体和失败的标签都被报告了一样)。
当我开始向下面的方法添加一个 OPTIONAL 子句时,这一点变得很清楚。
?prop wikibase:directClaim ?a .
行非常简单。 Wikibase 定义 directClaim
来将属性映射到实体。然后,这允许它定义有关属性(即标签)的元组。许多其他本体只是使用相同的标识符。
我的第二种(更通用的方法)是您在许多书籍和在线教程中找到的方法。这里的问题是 wikibase 的属性中有完整的 URL,我需要将它们转换成一个实体。我尝试了字符串操作,但这会产生一个字符串文字 - 而不是一个实体。解决方法是再次使用directClaim
:
?prop wikibase:directClaim ?a .
?prop rdfs:label ?propLabel. filter(lang(?propLabel) = "en").
请注意,如果定义了 rdfs:label
,这只是 return 的结果。即使没有定义标签,添加可选也会 return 结果。
我正在使用 SPARQLWrapper 将 SPARQL 查询发送到维基数据。
目前我正在尝试查找实体的所有属性。例如。使用一个简单的元组,例如:wd:Q11663 ?a ?b.
这本身有效,但我试图为返回的属性和实体找到人类可读的标签。
虽然 SERVICE wikibase:label
使用 Wikidata 的 GUI 界面工作,但这不适用于 SPARQLWrapper - 它坚持为变量及其 'label'.
查询 属性 rdfs:label
适用于实体 (?b),但此方法不适用于 属性 (?a)。
看起来 属性 作为完整的 URI 返回,例如 http://www.wikidata.org/prop/direct/P1536
。使用 GUI 我可以成功查询 wd:P1536 ?a ?b.
。如果我将它作为第二个查询发送,这适用于 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 过滤器 - 如果我没有得到任何回报,通常会放弃它]
我在使用两种方法时遇到了问题 - 上面的代码混合了这两种方法。此外,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
定义,那么它只是 return 实体。 GUI 和 SPARQLWrapper(到 SPARQL 端点)只是以不同的顺序 return 处理结果 - 所以看起来我看到了很多 'failed' 输出(即实体和失败的标签都被报告了一样)。
当我开始向下面的方法添加一个 OPTIONAL 子句时,这一点变得很清楚。
?prop wikibase:directClaim ?a .
行非常简单。 Wikibase 定义 directClaim
来将属性映射到实体。然后,这允许它定义有关属性(即标签)的元组。许多其他本体只是使用相同的标识符。
我的第二种(更通用的方法)是您在许多书籍和在线教程中找到的方法。这里的问题是 wikibase 的属性中有完整的 URL,我需要将它们转换成一个实体。我尝试了字符串操作,但这会产生一个字符串文字 - 而不是一个实体。解决方法是再次使用directClaim
:
?prop wikibase:directClaim ?a .
?prop rdfs:label ?propLabel. filter(lang(?propLabel) = "en").
请注意,如果定义了 rdfs:label
,这只是 return 的结果。即使没有定义标签,添加可选也会 return 结果。