首先,我将使用DBpedia SPARQL 端点中定义的前缀,以便我们可以复制和粘贴查询。我认为唯一的区别是dbo
现在将是dbpedia-owl
。其次,您正在使用许多原始数据属性,但如果可以,您应该尝试使用本体中的属性,如本答案中所述。这不一定会影响您在此处获得的结果,但如果您使用本体属性,您通常会获得更清晰的数据。
修改您的查询
FILTER NOT EXISTS 用于删除已结束的国家/地区
让我们先稍微清理一下查询,然后处理获取各种人口属性的问题。删除具有结束日期的国家/地区可以更简单一些。代替
OPTIONAL {?country dbpprop:yearEnd ?yearEnd}
FILTER (!bound(?yearEnd))
您可以使用它FILTER NOT EXISTS
来使其更直接:
FILTER NOT EXISTS { ?country dbpprop:yearEnd ?yearEnd }
在尝试使用 DBpedia 本体中的属性而不是原始信息框数据属性时,您可能需要考虑使用dbpedia-owl:dissolutionYear
而不是dbpprop:yearEnd
,给出:
FILTER NOT EXISTS { ?country dbpedia-owl:dissoluationYear ?yearEnd }
简化语言过滤
期望值是文字是合理的rdfs:label
,并且该lang
函数要求其参数是文字,因此您实际上不需要绑定str(?enName)
到?name
; 只需绑定?name
三重模式就足够了,然后检查它的语言(您正在正确地使用它langMatches
)。也就是说,而不是
?country rdfs:label ?enName .
FILTER (langMatches(lang(?enName), "en"))
BIND (str(?enName) AS ?name)
你可以使用
?country rdfs:label ?name .
FILTER (langMatches(lang(?name), "en"))
这确实意味着您返回的名称将带有语言标签。如果你真的只想要纯字符串,你可以像以前一样绑定,或者as
在选择中创建一个表达式,例如,
SELECT DISTINCT (str(?name) as ?noLangName) ?population
检查人口是否有界并且是一个数字
我认为过滤也不xsd:integer(?population)
会对您有太大帮助。该表示法不是类型谓词,而是一个转换函数,因此?population
被转换为整数,我认为过滤器将始终让值通过,除非在 的情况下0
,这会失败。您仍然想知道一个国家是否有人口0
,对吗?但是,您只需要有人口的国家/地区,因此您可以使用以下内容进行过滤bound
:
FILTER(bound(?population))
然而,由于这里的属性是原始信息框属性,数据中有一些噪音,所以我们最终得到的值是
"Denmark"@en "- Density 57,695"@en
"Denmark"@en "- Faroe Islands"@en
这是没有用的。更好的过滤器只会检查该值是否为数字(这将隐含地要求它被绑定),并且有一个isNumeric
用于此目的的函数,因此我们使用:
FILTER (isNumeric(?population))
使用 VALUES 简化类似的 UNION 模式
您可以UNION
使用VALUES
. UNION
您可以定义一个?hasCode
仅具有 valuesdbpprop:iso3166code
等的变量,而不是几个几乎相同的模式。即,而不是:
{ ?country dbpprop:iso3166code ?code . }
UNION
{ ?country dbpprop:iso31661Alpha ?code . }
UNION
{ ?country dbpprop:countryCode ?code . }
UNION
{ ?country a yago:MemberStatesOfTheUnitedNations . }
您可以使用:
values ?hasCode { dbpprop:iso3166code dbpprop:iso31661Alpha dbpprop:countryCode }
{ ?country ?hasCode ?code . }
UNION
{ ?country a yago:MemberStatesOfTheUnitedNations . }
?population
您可以对检索执行类似的操作:
OPTIONAL {?country dbpprop:populationEstimate ?population}
OPTIONAL {?country dbpprop:populationCensus ?population}
可以变成:
values ?hasPopulation { dbpprop:populationEstimate dbpprop:populationCensus }
OPTIONAL { ?country ?hasPopulation ?population }
最终结果
重写后的查询现在是:
SELECT DISTINCT ?name ?population
WHERE {
?country a dbpedia-owl:Country .
?country rdfs:label ?name .
FILTER (langMatches(lang(?name), "en"))
values ?hasPopulation { dbpprop:populationEstimate dbpprop:populationCensus }
OPTIONAL { ?country ?hasPopulation ?population }
FILTER (isNumeric(?population))
FILTER NOT EXISTS { ?country dbpedia-owl:dissolutionYear ?yearEnd }
values ?hasCode { dbpprop:iso3166code dbpprop:iso31661Alpha dbpprop:countryCode }
{ ?country ?hasCode ?code . }
UNION
{ ?country a yago:MemberStatesOfTheUnitedNations . }
}
SPARQL 结果
印度现在出现在人口的结果中:
"India"@en 1210193422