SPARQL中具有相同名称的两个/并行/左连接的正确语法(可能使用OPTIONAL)

时间:2014-04-16 21:58:37

标签: sparql dbpedia

我阅读了OPTIONAL here的语法,并且在OPTIONAL上也遵循了this slideshow。我认为我的问题归结为没有正确的语法,给定一个基本集,左边连接一个或另一个字段,无论哪个存在。

我的理解是,OPTIONAL子句按顺序执行,所以我也试图利用这个来按顺序填写“大学”变量,以便我信任数据字段。

我的示例查询试图找到哪些教育机构拥有最多的美国小姐校友。(我之所以选择这个,是因为它很有趣,但是设置相当小,足以调试。 )

至少有两个字段似乎适合识别教育校友联盟dbpedia-owl:educationdbpedia2:almaMater

我的第一个查询,只是拉动dbpedia-owl:education:

SELECT count(distinct(?ma)) as ?people, ?University WHERE {
{
    ?ma dbpedia2:title :Miss_America ;
       rdf:type <http://dbpedia.org/ontology/Person> .
} UNION {
    ?ma <http://dbpedia.org/ontology/title> ?title;
       rdf:type <http://dbpedia.org/ontology/Person> .
    FILTER STRSTARTS(?title, "Miss America") .
}
    OPTIONAL {
             ?ma dbpedia-owl:education ?University 
      }
    OPTIONAL { ?ma dbpedia-owl:birthDate ?bday . }
}
ORDER BY DESC(?people)

SPARQL RESULTS

我的第二个查询,只是拉动dbpedia2:almaMater:

SELECT count(distinct(?ma)) as ?people, ?University WHERE {
{
    ?ma dbpedia2:title :Miss_America ;
       rdf:type <http://dbpedia.org/ontology/Person> .
} UNION {
    ?ma <http://dbpedia.org/ontology/title> ?title;
       rdf:type <http://dbpedia.org/ontology/Person> .
    FILTER STRSTARTS(?title, "Miss America") .
}
    OPTIONAL { ?ma dbpedia2:almaMater ?University }
    OPTIONAL { ?ma dbpedia-owl:birthDate ?bday . }
}
ORDER BY DESC(?people)

SPARQL RESULTS

正如你所看到的,我需要要求两种方式来表达Alma Mater,因为它们捕获了不同的东西。

然而,两种形式的联合可选NESTED(III)和UNION(IV)似乎都留下了(I)或(II)中的项目。也没有真正给我提供我正在寻找的上述可选联盟。

这是NESTED表格:

SELECT count(distinct(?ma)) as ?people, ?University WHERE {
{
    ?ma dbpedia2:title :Miss_America ;
       rdf:type <http://dbpedia.org/ontology/Person> .
} UNION {
    ?ma <http://dbpedia.org/ontology/title> ?title;
       rdf:type <http://dbpedia.org/ontology/Person> .
    FILTER STRSTARTS(?title, "Miss America") .
}
    OPTIONAL {
             ?ma dbpedia-owl:education ?University 
             OPTIONAL { ?ma dbpedia2:almaMater ?University }
      }
    OPTIONAL { ?ma dbpedia-owl:birthDate ?bday . }
}
ORDER BY DESC(?people)

SPARQL RESULTS

这是UNION表格:

SELECT count(distinct(?ma)) as ?people, ?University WHERE {
{
    ?ma dbpedia2:title :Miss_America ;
       rdf:type <http://dbpedia.org/ontology/Person> .
} UNION {
    ?ma <http://dbpedia.org/ontology/title> ?title;
       rdf:type <http://dbpedia.org/ontology/Person> .
    FILTER STRSTARTS(?title, "Miss America") .
}
    OPTIONAL {{ ?ma dbpedia-owl:education ?University } UNION
             { ?ma dbpedia2:almaMater ?University } .
      }
    OPTIONAL { ?ma dbpedia-owl:birthDate ?bday . }
}
ORDER BY DESC(?people)

SPARQL RESULTS

当我只是枚举名称,(I)和(II)而没有聚合时,回顾我得到的东西,似乎这些,(III)或(IV)中的任何一个都没有给我正确的回报集,包含来自(I)OR(II)的数据。我理解我可以单独执行查询然后使用脚本语言进行合并,或者可能将两者都分配为不同的可选子句变量,但它看起来很笨拙。 (但如果这是推荐的方式,请告诉我。)

因此,要简明扼要地提出这个问题:

  • 如何判断将返回所有被命名为Miss America的候选人的查询,加入EITHER:almaMater或:education,以哪个存在?

此外,我注意到最近的美国小姐Nina Davuluri没有出现在dbpedia端点的搜索结果中,尽管她在List_of_Miss_America_titleholders的搜索框中。我如何调查wikidata和dbpedia端点之间差异的原因(以及如何帮助提供数据?)

1 个答案:

答案 0 :(得分:1)

首先,如果您提供完整的SPARQL查询(包括前缀(尤其是因为您使用了一些非标准的查询),或者使用与公共端点相同的前缀,它会更容易提供帮助用户界面(见http://dbpedia.org/sparql?nsdecl)。它不能立即清楚dbpedia2是什么等等(尽管我现在意识到在您链接到的SNORQL资源管理器中定义了dbpedia2

另外,请注意,虽然Virtuoso可能会接受您的查询,但它们并非实际上都是合法的SPARQL。例如,如果您进行第一次查询并转到http://sparql.org/validate/query,您会发现变量投影语法不合法。它必须是

select (count(distinct(?ma)) as ?people) ?University where

其中… as ?people包含在括号中,并且变量之间没有逗号。 (这不是问题,但您也可以使用count(distinct ?ma)并保存两个括号。)

接下来,由于DBpedia数据基于维基百科,这意味着它有时可能有点混乱,因此有点想要浏览数据以找到识别事物的最佳方法。在这种情况下,通过查看http://dbpedia.org/page/Angela_Perez_Baraquio,似乎是一种识别美国小姐获胜者的好方法,可以寻找拥有dcterms:subject category:Miss_America_winners的人。因此,我们有一个类似的查询:

select ?person where {
  ?person a dbpedia-owl:Person ;
          dcterms:subject category:Miss_America_winners
}

SPARQL results

现在,并非所有这些都具有干净的教育/母校/等信息,但您可以使用|的替代属性路径来使用任意数量的属性。然后你最终得到这样的查询(对于三个属性):

select ?education (count(distinct ?person) as ?numWinners) where {
  ?person a dbpedia-owl:Person ;
          dcterms:subject category:Miss_America_winners .
  optional { 
    ?person dbpprop:education|dbpprop:almaMater|dbpedia-owl:almaMater ?education 
  }
}
group by ?education

SPARQL results

它不是特别有启发性;最大的共同点是那些没有价值的人。对于其他值,可以混合使用字符串和资源。如果不出意外,密西西比大学有两个。

选择属性中的属性值在SPARQL中实际上并不是完全无关紧要的,并且已经在这个answers.semanticweb.com问题中讨论了Preference patterns for SPARQL (1.1)。有几种方法可以做到这一点,但我认为最简单的方法是匹配可选块中的所有属性,然后coalesce将它们合并为一个:

select ?person ?education where {
  ?person a dbpedia-owl:Person ;
          dcterms:subject category:Miss_America_winners .
  optional { ?person dbpedia-owl:almaMater ?ed1 }
  optional { ?person dbpprop:almaMater ?ed2 }
  optional { ?person dbpprop:education ?ed3 }
  bind( coalesce(?ed1,?ed2,?ed3) as ?education )
}

SPARQL results

对于具有多个属性值的个人,我们会获得首选属性。例如,对于http://dbpedia.org/resource/Angela_Perez_Baraquio,我们得到dbpedia-owl:almaMaterhttp://dbpedia.org/resource/University_of_Hawaii。对于最佳属性有多个值的情况,我们仍然可以获得所有这些值。例如,http://dbpedia.org/resource/Kylene_Barkerhttp://dbpedia.org/resource/Virginia_Techhttp://dbpedia.org/resource/Carroll_County_High_School_(Hillsville,_Virginia)