SPARQL:如果第一个选项不可用,如何获取可用语言的标签

SPARQL: How to obtain label in available languages if first option is not available

如果我的查询返回的维基数据资源在我筛选的语言中没有可用标签,我会得到一个空单元格。

SELECT *
WHERE
{
    ?country wdt:P31 wd:Q6256.
    ?country rdfs:label ?country_name
        FILTER(LANG(?country_name) = 'jbo').
}

link

如果第一种语言失败,如何请求以任何一种可用语言返回标签?

首先,首选langMatches来检查语言标签。这在您的情况下尤其重要,因为例如您可能想要一个英文标签,并且 langMatches(lang(?label), "en") 会找到一个标签带有标签 "en"、"en-GB" 或 "en-US" 等。这些是该语言的区域变体,langMatches 可以帮助您找到它们.

根据评论更新了解决方案

@svick 在评论中注意到,原始解决方案以英文名称与非英文名称的笛卡尔积中的每个元素结束。您可以通过使用 select distinct 来避免这种情况。但确实有更好的方法:只需在两个 optional 中使用相同的变量;第一个检查英文标签,第二个检查非英文标签。如果第一个成功,则第二个永远不会被调用。也就是说,只需执行:

select ?country ?label {
   ?country wdt:P31 wd:Q6256 
   optional { 
     ?country rdfs:label ?label
     filter langMatches(lang(?label), "en")
   }
   optional { 
     ?country rdfs:label ?label
   }
}

其他选项

  • 如果您需要进行任何聚合,您可能会在 SPARQL filter language if possible in multiple value context 中找到一些帮助。
  • 如果在第一种语言之后,您仍然对其余语言有偏好,您可能会发现 Sparql multi lang data compression to one row 中使用的技术很有帮助。


COALESCE 的原始解决方案

不过在那之后,coalesce 会做你想做的事。它需要多个参数,returns 第一个有值的参数。因此,您可以在 optional 块中匹配首选语言,在另一个块中匹配任何语言,并合并值:

select distinct ?country (coalesce(?enLabel, ?anyLabel) as ?label) {
   ?country wdt:P31 wd:Q6256 
   optional { 
     ?country rdfs:label ?enLabel
     filter langMatches(lang(?enLabel), "en")
   }
   optional { 
     ?country rdfs:label ?anyLabel
   }
}