SPARQL查询从DBpedia检索国家人口

SPARQL查询从DBpedia检索国家人口,sparql,dbpedia,Sparql,Dbpedia,我开发了下面的SPARQL查询,以从DBpedia获取人口众多的国家列表。我使用欧盟条款来确定哪些资源是当前国家,因为不同国家之间的信息不一致,例如,国家代码有不同的标准,其中一些甚至没有标准 现在我遇到的问题是,一些国家有一个dbpprop:populationEstimate属性,但其他国家有dbpprop:populationCensus属性,我不知道如何让它们都绑定?population。现在我只得到估计总体,我想这是因为有两个可选的子句来匹配?总体没有意义,但我无法更接近解决方案 例如

我开发了下面的SPARQL查询,以从DBpedia获取人口众多的国家列表。我使用欧盟条款来确定哪些资源是当前国家,因为不同国家之间的信息不一致,例如,国家代码有不同的标准,其中一些甚至没有标准

现在我遇到的问题是,一些国家有一个
dbpprop:populationEstimate
属性,但其他国家有
dbpprop:populationCensus
属性,我不知道如何让它们都绑定
?population
。现在我只得到估计总体,我想这是因为有两个
可选的
子句来匹配
?总体
没有意义,但我无法更接近解决方案

例如,have
dbpprop:populationCensus
,但它不会出现在结果中

PREFIX dbpprop: <http://dbpedia.org/property/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX yago:<http://dbpedia.org/class/yago/>
PREFIX dbo: <http://dbpedia.org/ontology/>
PREFIX category: <http://dbpedia.org/resource/Category:>
PREFIX xsd:<http://www.w3.org/2001/XMLSchema#>

SELECT DISTINCT ?name ?population
WHERE {
    ?country a dbo:Country .
    ?country rdfs:label ?enName .   

    OPTIONAL {?country dbpprop:populationEstimate ?population}
    OPTIONAL {?country dbpprop:populationCensus ?population}
    OPTIONAL {?country dbpprop:yearEnd ?yearEnd}

    { ?country dbpprop:iso3166code ?code . }
    UNION
    { ?country dbpprop:iso31661Alpha ?code . }
    UNION
    { ?country dbpprop:countryCode ?code . }
    UNION
    { ?country a yago:MemberStatesOfTheUnitedNations . }

    FILTER (langMatches(lang(?enName), "en")) 
    FILTER (!bound(?yearEnd))
    FILTER (xsd:integer(?population))
    BIND (str(?enName) AS ?name)
}
前缀dbpprop:
前缀rdfs:
前缀yago:
前缀dbo:
前缀类别:
前缀xsd:
选择不同的“名称”填充
在哪里{
?国家a dbo:国家。
?国家RDF:标签?名称。
可选{国家/地区dbpprop:populationEstimate?population}
可选{?国家dbpprop:人口普查?人口}
可选{国家/地区dbpprop:yearEnd?yearEnd}
{?国家dbpprop:iso3166code?代码。}
联合
{?国家dbpprop:iso31661Alpha?代码。}
联合
{?国家dbpprop:countryCode?代码。}
联合
{国家a雅戈:成员国联合国。}
过滤器(langMatches(lang(?enName),“en”))
过滤器(!绑定(?年终))
过滤器(xsd:integer(?population))
绑定(str(?enName)AS?name)
}
谢谢大家的帮助:)

如何解决这个问题 我想我知道你如何解决这个问题

对于可选子句,使用单独的变量

OPTIONAL {?country dbpprop:populationEstimate ?populationEstimate}
OPTIONAL {?country dbpprop:populationCensus ?populationCensus}
OPTIONAL {?country dbpprop:yearEnd ?yearEnd}
然后,将其中一个绑定到
?population

BIND(IF(bound(?populationEstimate), ?populationEstimate, ?populationCensus) as ?population)
最后,检查过滤器表达式中的绑定变量

FILTER (xsd:integer(?population))
查询的其余部分保持不变。我已经对dbpediasparql端点进行了测试,乍一看,似乎得出了正确的结果

让我知道这是否正确

完整查询
前缀dbpprop:
前缀rdfs:
前缀yago:
前缀dbo:
前缀类别:
前缀xsd:
选择不同的“名称”填充
在哪里{
?国家a dbo:国家。
?国家RDF:标签?名称。
可选{国家/地区dbpprop:populationEstimate?populationEstimate}
可选{国家/地区dbpprop:populationCensus?populationCensus}
可选{国家/地区dbpprop:yearEnd?yearEnd}
绑定(如果(绑定(?populationEstimate)、?populationEstimate、?populationCensus)作为人口)
过滤器(langMatches(lang(?enName),“en”))
过滤器(!绑定(?年终))
过滤器(xsd:integer(?population))
{?国家dbpprop:iso3166code?代码。}
联合
{?国家dbpprop:iso31661Alpha?代码。}
联合
{?国家dbpprop:countryCode?代码。}
联合
{国家a雅戈:成员国联合国。}
绑定(str(?enName)AS?name)
}

首先,我将使用中定义的前缀,以便复制和粘贴查询。我认为唯一的区别是
dbo
现在将是
dbpediaowl
。第二,您正在使用许多原始数据属性,但是如果可以,您应该尝试使用本体中的属性,如中所述。这并不一定会影响您在这里得到的结果,但是如果您使用本体属性,通常会得到更清晰的数据

修改您的查询 不存在用于删除已结束的国家/地区的筛选器 让我们先稍微整理一下查询,然后讨论获取各种总体属性的问题。删除有结束日期的国家可以做得更简单一些。而不是

OPTIONAL {?country dbpprop:yearEnd ?yearEnd}
FILTER (!bound(?yearEnd))
?country rdfs:label ?enName .   
FILTER (langMatches(lang(?enName), "en")) 
BIND (str(?enName) AS ?name)
您可以使用以下命令使其更直接:

FILTER NOT EXISTS { ?country dbpprop:yearEnd ?yearEnd }

试图从DbPeDATA本体中使用属性优先于原始信息框数据属性时,您可能需要考虑使用<代码> DbPedieOWL:解散年而不是<代码> dppPRP:年终,给出:

FILTER NOT EXISTS { ?country dbpedia-owl:dissoluationYear ?yearEnd }
简化语言过滤 有理由期望
rdfs:label
值为文本,而
lang
函数要求其参数为文本,因此您实际上不需要将
str(?enName)
绑定到
?name
;只需在三元组模式中绑定
?name
,然后检查其语言(使用
langMatches
)就足够了。也就是说,而不是

OPTIONAL {?country dbpprop:yearEnd ?yearEnd}
FILTER (!bound(?yearEnd))
?country rdfs:label ?enName .   
FILTER (langMatches(lang(?enName), "en")) 
BIND (str(?enName) AS ?name)
你可以用

?country rdfs:label ?name .   
FILTER (langMatches(lang(?name), "en"))
这意味着您返回的名称将有一个语言标记。如果您确实只需要普通字符串,则可以像以前一样绑定,或者在select中创建一个
as
表达式,例如

SELECT DISTINCT (str(?name) as ?noLangName) ?population
检查人口是否有界且是否为数字 我认为对
xsd:integer(?population)
进行过滤也不会对您有多大帮助。该表示法不是类型谓词,而是一个强制转换函数,因此
?population
被强制转换为整数,我认为过滤器将始终允许值通过,除非
0
,否则会失败。不过,你还是想知道一个国家的人口是否为
0
,对吗?但是,您只需要人口众多的国家,因此可以使用以下内容进行筛选:

但是,由于这里的属性是原始的infobox属性,因此数据中存在一些噪声,因此我们最终得到如下值

"Denmark"@en "- Density 57,695"@en
"Denmark"@en "- Faroe Islands"@en
这些都没用。更好的过滤器只需检查值是否为数字(这将隐含地要求它是绑定的),并且有一个函数用于此目的,因此我们使用:

FILTER (isNumeric(?population))
用值简化相似的并集模式 您可以使用清理
联合
模式。您可以定义一个变量
?hasCode
{ ?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 . }
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 . }
}
"India"@en 1210193422