好的SPARQL查询,用于查找所有以资源作为主语或宾语的三元组

7

我需要在DBpedia中找到所有以http://dbpedia.org/resource/Benin作为主语或宾语的三元组。这个查询可以给我想要的输出格式(只有三个变量,没有空格):

PREFIX : <http://dbpedia.org/resource/>
SELECT * WHERE {
?s ?p ?o
FILTER (?s=:Benin OR ?o=:Benin)
}

如果我执行以下查询,我会得到类似的结果:
PREFIX : <http://dbpedia.org/resource/>
SELECT * WHERE {
{:Benin ?p ?o}
UNION
{?s ?p :Benin}
}

然而,后者的格式有误。它首先给出了po的输出,留下了空白的s,然后是sp的输出,留下了空白的o。此外,第一个查询需要更长的执行时间。我将感激您解释这两个查询的机制以及为什么输出会有差异。

在SPARQL中,“OR”用“||”拼写。 - AndyS
@AndyS 是的,但是dbpedia的后端专家似乎并不在意,尽管我在源代码层面上找不到确认。 - dhke
2个回答

5
然而,后者的格式有问题。
这是因为两个查询与 SELECT * 一起具有不同的结果集。Union 将元组连接在一起,但由于某些元组缺少部分内容,所以会得到扭曲的输出。
您可以通过显式列出和选择变量来解决这个问题。
PREFIX : <http://dbpedia.org/resource/>
SELECT ?s ?p ?o WHERE {
   {
       ?s ?p ?o
       FILTER (?s=:Benin)
   }
   UNION 
   {
       ?s ?p ?o .
       FILTER (?o=:Benin)
   }
}

请注意,在dbpedia上使用此方法仍比使用OR过滤器快得多。
当元组与两个过滤表达式都匹配时(即:Benin ?p :Benin),联合将返回重复项。为了解决这个问题,可以使用SELECT DISTINCT,但这会增加额外的成本,并且由于看起来问题不存在,所以我省略了它以提高性能。
引用:

此外,第一个查询需要更长时间才能执行。

很难说没有EXPLAIN()的结果,但我的第一个猜测是相等过滤器正在使用索引,而OR过滤器正在使用全表扫描。Virtuoso对嵌套过滤器似乎没有生成良好的查询计划

3
尝试这个:点击这里 --
PREFIX : <http://dbpedia.org/resource/>
DESCRIBE  :Benin

"-- 或者只是 --"
DESCRIBE  <http://dbpedia.org/resource/Benin>

您可以获取各种其他序列化格式的输出,包括N-triples

这很美丽 :-) - kurious
请问您能演示一下如何选择序列化格式吗? - kurious
此外,这是关于SPARQL 1.1官方文档中的DESCRIBE的内容: “DESCRIBE形式返回一个包含有关资源的RDF数据的单个结果RDF图形...描述由查询服务确定。”鉴于此,我们可以假设DBpedia通过DESCRIBE提供有关资源的所有信息(特别是当结果具有超过2k三元组时)。 - kurious
2
公共DBpdia端点在所有功能中都有结果集大小限制。如果您想要无限的结果,您需要追求经过身份验证的访问,或者获取自己的实例。由于各种原因,DESCRIBE输出可能与您开始的SELECT不完全匹配;对此的后续跟进可能最好通过Virtuoso用户邮件列表进行。 - TallTed
1
序列化格式可以通过SPARQL提交表单上的菜单(目前是最完整的列表)或使用&format= URL参数或SPARQL查询中的define output:format pragma来选择。 - TallTed

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接