【问题标题】:SPARQL Distinct pairsSPARQL 不同对
【发布时间】:2015-06-04 21:54:42
【问题描述】:

我有一张桌子,上面有作者相同的文档。我需要获取不同的文档对。我做了以下事情:

SELECT DISTINCT ?d1 ?d2  WHERE {
?d1 myns:creator ?x.
?d2 myns:creator ?y.
FILTER (?x=?y && ?d1!=?d2).
}
GROUP BY ?d1 ?d2

但是DOC1, DOC2 和DOC2, DOC1 都在结果中。我需要摆脱其中一对。 这是整个三元组数据库:

@prefix xsd:  <http://www.w3.org/2001/XMLSchema#> . 
@prefix rdf:  <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix myns: <http://my.local.namespace#> .

_:doc1 rdf:type myns:Document.
_:doc1 myns:creator _:Pete.
_:doc1 myns:year "2000"^^xsd:integer.
_:doc1 myns:publisher _:p1.

_:doc2 rdf:type myns:Document.
_:doc2 myns:creator _:John.
_:doc2 myns:year "2004"^^xsd:integer.
_:doc2 myns:publisher _:p2.


_:doc3 rdf:type myns:Document.
_:doc3 myns:creator _:Pete.
_:doc3 myns:publisher _:p3.

_:doc4 rdf:type myns:Document.
_:doc4 myns:creator _:Bob.
_:doc4 myns:year "2010"^^xsd:integer.
_:doc4 myns:publisher _:p2.

_:Pete rdf:type myns:Person.
_:Pete myns:knows _:Bob.
_:Pete myns:knows _:John .

_:John rdf:type myns:Person.
_:John myns:age "29"^^xsd:integer.
_:John myns:knows _:Bob.

_:Bob rdf:type myns:Person.
_:Bob myns:age "35"^^xsd:integer.

执行查询后得到的结果是:

D1  D2
_:891f1e98-b411-4e54-9533-18d530f09c6ddoc1  _:891f1e98-b411-4e54-9533-18d530f09c6ddoc3
_:891f1e98-b411-4e54-9533-18d530f09c6ddoc3  _:891f1e98-b411-4e54-9533-18d530f09c6ddoc1

值得注意的是,从技术上讲,这两对是相同的。我需要一个不同的(即其中一个就足够了)。我不确定环境特征。但是有芝麻框架

【问题讨论】:

  • 从您对我的回答的 cmets 来看,您的问题缺少基本信息。您需要显示complete, minimal, verifiable example,包括您正在执行此操作的 实际 数据的最小样本(我们可以复制粘贴到三重存储中),您的输出 期望 得到,以及你实际得到的输出。如果您告诉我们您正在使用哪种软件(哪种 SPARQL 引擎、哪种数据库、哪种编程语言等),也会有很大帮助。
  • @JeenBroekstra,已更新。
  • 谢谢,现在清楚多了。

标签: sparql sesame


【解决方案1】:

这将适用于一些系统:

SELECT ?d1 ?d2  WHERE {
  ?d1 myns:creator ?x.
  ?d2 myns:creator ?y.
  FILTER (?x=?y && STR(IRI(?d1)) < STR(IRI(?d2))).
}

?d1 和 ?d2 将是空白节点。但是空白节点是空白的。 因此,要为&lt; 提供排序,我们需要某种查询范围的标签或与每个标签相关联的值。

您的数据没有任何区分每个人的三元组。最好在数据中输入真实姓名:

_:Pete rdfs:label "Pete" .

更好的是,使用FOAF 词汇表。

一些系统允许IRI() 中的空白节点 - 从技术上讲,它是 SPARQL 规范的扩展。然后您可以填写STR 表格并进行比较。对我来说适用于你的数据(Apache Jena) - 你没有说你正在使用哪个 RDF 系统。

最好的解决方案是将区分信息放入数据中。

【解决方案2】:

您可以通过一个小技巧来做到这一点:将!= 转换为&lt;(或&gt;),并将值转换为字符串,这样您就可以进行词法比较:

SELECT DISTINCT ?d1 ?d2  WHERE {
?d1 myns:creator ?x.
?d2 myns:creator ?y.
FILTER (?x=?y && STR(?d1) < STR(?d2)).
}
GROUP BY ?d1 ?d2

这适用于任何一对不相等的标识符,一个标识符总是大于另一个的想法(通过词法排序)。因此,在任何两对中,实际上只会选择一对。

更新现在您已经显示了您的数据,我们可以看到问题在于您没有使用 IRI 来区分您的文档,而是使用空白节点。上面的查询不起作用,因为根据 SPARQL 标准,空白节点是无序的(所以直接通过 &lt; 比较是行不通的),而且,STR 函数被定义为只对字面量或 IRI 进行操作,而不是对空白节点。

最好的解决方案是更改您的数据,并确保您使用正确的 IRI,因为无论您是否可以通过某种方式使此查询对这些数据起作用,结果几乎是无用的:空白节点在它们之外没有任何意义本地范围,因此您的查询返回的文档标识符不能真正被重用;例如,您将无法执行 SPARQL 查询来获取专门用于文档 _:doc1 的任何属性(尽管公平地说,芝麻在 API 中有一个解决方法)。

顺便说一句,将空白节点更改为 IRI 的一种非常简单的方法是将龟文件中所有出现的 _: 替换为 myns:。

【讨论】:

  • 啊,您可能需要先显式转换为字符串。已编辑。
  • 那么你需要提供很多关于你的设置和你的实际数据是什么样子的额外细节。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-03
  • 2016-11-10
  • 1970-01-01
  • 2016-07-25
  • 1970-01-01
相关资源
最近更新 更多