我想使用sparql选择数据属性值,并对其语言有一些限制:
目前的查询是:
select distinct ?dataProperty ?dpropertyValue where {
<http://dbpedia.org/resource/Blackmore's_Night> ?dataProperty ?dpropertyValue.
?dataProperty a owl:DatatypeProperty.
FILTER ( langmatches(lang(?dpropertyValue),"ru") || langmatches(lang(? dpropertyValue),"en") || lang(?dpropertyValue)="" )
}
它的问题:结果包含两行摘要(ru + en)。我只想要一行,其中应包含ru。如果ru不可用,我想得到en等。 怎么样?
答案 0 :(得分:1)
假设您有这样的数据:
@prefix : <http://stackoverflow.com/q/21531063/1281433/> .
:a a :resource;
:p "a in english"@en, "a in russian"@ru .
:b a :resource ;
:p "b in english"@en .
然后你希望得到这样的结果:
--------------------------------
| resource | label |
================================
| :b | "b in english"@en |
| :a | "a in russian"@ru |
--------------------------------
以下是两种方法。
这种方式使用随values
提供的SPARQL 1.1子查询,聚合和数据。我们的想法是使用values
将每个语言标记与排名相关联。然后使用子查询在资源具有的所有标签上拉出最佳排名。然后在外部查询中,您可以访问最佳排名,并且只需使用与该排名对应的语言检索标签。
prefix : <http://stackoverflow.com/q/21531063/1281433/>
select ?resource ?label where {
# for each resource, find the rank of the
# language of the most preferred label.
{
select ?resource (min(?rank) as ?langRank) where {
values (?lang ?rank) { ("ru" 1) ("en" 2) }
?resource :p ?label .
filter(langMatches(lang(?label),?lang))
}
group by ?resource
}
# ?langRank from the subquery is, for each
# resource, the best preference. With the
# values clause, we get just the language
# that we want.
values (?lang ?langRank) { ("ru" 1) ("en" 2) }
?resource a :resource ; :p ?label .
filter(langMatches(lang(?label),?lang))
}
您可以为您正在考虑的每种语言选择一个可选标签,然后按照您的偏好顺序coalesce
进入(以便获得第一个受限制的语言)。这有点冗长,但如果您需要使用除最优选语言之外的各种语言的标签,您可以访问它们。
prefix : <http://stackoverflow.com/q/21531063/1281433/>
select ?resource ?label where {
# find resources
?resource a :resource .
# grab a russian label, if available
optional {
?resource :p ?rulabel .
filter( langMatches(lang(?rulabel),"ru") )
}
# grab an english label, if available
optional {
?resource :p ?enlabel .
filter( langMatches(lang(?enlabel),"en") )
}
# take either as the label, but russian over english
bind( coalesce( ?rulabel, ?enlabel ) as ?label )
}