【发布时间】:2019-12-10 17:26:12
【问题描述】:
我正在尝试将一些本地数据与 DBpedia 相关联,以提取有关国家经济统计数据的信息。如何补偿不同长度的备用路径?该字段本身是OPTIONAL,因此如果查询恰好没有列出语言,则不会错过结果,但是我在确实列出语言的资源上得到空白的language列。
例如,http://dbpedia.org/page/Netherlands、http://dbpedia.org/page/Ireland 和 http://dbpedia.org/page/Italy 索引不同的语言,从字符串到引用资源的不同谓词:
荷兰:
爱尔兰:
意大利:
这是一个(精简的)示例查询,有点可以工作,但不是很好:
SELECT DISTINCT
?countryName
?dbEntry
(GROUP_CONCAT(DISTINCT ?dbLanguage; separator=", ") AS ?languages)
WHERE
{
?dbEntry a dbo:Place ;
rdfs:label | dbo:longName ?countryName .
# For some reason, stacking two OPTIONALs and BINDing is all that seems to work here, and still not 100%
OPTIONAL {
?dbEntry dbo:language / foaf:name ?dbofLanguage .
BIND(?dbofLanguage AS ?dbLanguage) .
}
OPTIONAL {
?dbEntry dbp:languages ?dbpLanguage .
BIND(?dbpLanguage AS ?dbLanguage) .
}
FILTER (STR(?countryName) IN ("Netherlands", "Italy", "Ireland")) .
}
GROUP BY ?countryName ?dbEntry
LIMIT 3
您会看到返回的结果格式完全不同:
我想写一些类似的东西
OPTIONAL {
?dbEntry (dbo:language / foaf:name) | (dbp:languages / rdfs:label) | dbp:languages ?language
}
但我认为 SPARQL 还不支持任何复杂的东西? (我得到零结果)
【问题讨论】:
-
您的属性路径有效,它只是 Virtuoso 的随时功能,它返回它可以在给定时间内计算的内容。您应该使用更好的过滤器进行调试,即使用
VALUES ?dbEntry {dbr:Netherlands dbr:Italy dbr:Ireland}而不是太贵的FILTER。您还应该将?countryName限制为仅限英语,否则您将获得国家标签的每种语言的多行。 -
SELECT DISTINCT ?countryName ?dbEntry (GROUP_CONCAT(DISTINCT ?language; separator=", ") AS ?languages) WHERE { VALUES ?dbEntry {dbr:Netherlands dbr:Italy dbr:Ireland} ?dbEntry a dbo:Place ; rdfs:label | dbo:longName ?countryName . filter(lang(?countryName) = 'en') # For some reason, stacking two OPTIONALs and BINDing is all that seems to work here, and still not 100% OPTIONAL { ?dbEntry (dbo:language / foaf:name) | (dbp:languages / rdfs:label) | dbp:languages ?language } } GROUP BY ?countryName ?dbEntry LIMIT 10 -
由于意大利有多个英文名称,因此这里仍然有两行表示意大利。我只是按 URI 分组并在名称上使用
group_concat或使用sample来获得一个名称。 -
@AKSW 啊,我听说过。我会使用
VALUES,但这实际上只是一个缩写查询——我在SERVICE块中使用它来匹配我自己的数据。如果我尝试只匹配我的本地子句和 DBpedia 的WHERE子句中的?countryName变量,它永远不会匹配 - 我认为这是一个语言问题。我可以在查询中对自己的数据指定@en吗? -
您可以直接在文字上使用它,例如
"Italy"@en- 但随后只需使用FILTER (?countryName) IN ( ...),因此不再需要STR函数