理论上RDF图是一个set三元组,这意味着每个三元组只能出现一次。当然,您可以有一个文档,例如在 Turtle 中,其中包含三元组或四元组的重复项,但在加载到内存/存储后,这些三元组应被视为一个。毕竟任何文档都只是文本。
也就是说,我看到了根据三重存储的不同行为。例如,AllegroGraph 默认加载并处理重复的三元组。有一个手动选项可以修剪重复项。
不,查询不会告诉您有重复的问题,因为 SPARQL 聚合适用于节点而不是整个三元组。
关于你的例子,有多种方法。
TL/DR您将需要一种方法来添加关于语句的语句。看这张幻灯片分享有多种方法,我在下面简要介绍了其中一些方法。
完整答案
最简单的是引入某种人工中介图节点,可以称为Mention管他呢。例如
:Susan :mentions [
rdf:type :Mention ;
:mentionsWhom :Bob ;
:times 5
]
问题是,如果您碰巧将这种结构引入到现有数据中,这会破坏现有的语义。
一种简单且广泛支持的方法是使用命名图这样你就有了quads而不是三元组。下面的示例增强了海龟语法,使其变为TriG。请注意,名称图只是另一个资源。使用任何 SPARQL 处理器也可以轻松查询命名图。
# :susanMentionsBob is the named graph
:susanMentionsBob {
:Susan :mentions :Bob
}
# we can say more about that graph
:susanMentionsBob :times 5
另一种传统的解决方案是使用一种形式具体化。通过具体化,您可以创建一个rdf:声明对象,您可以在其中添加附加数据。缺点是需要重复原来的三元组s/p/o
:Susan :mentions :Bob . # actual triple intact
_:reifiedStatement
rdf:type rdf:Statement ;
rdf:subject :Susan ;
rdf:predicate :mentions ;
rdf:object :Bob ;
:times 5 . # extra statement about the mention
最近引入了更简洁的具体化方法。您可以使用辛格尔顿房产反而。您引入了一个额外的谓词,它取代了:提到对于单一用途,您可以向该属性添加附加语句:
:Susan :mentions#1 :Bob .
:mentions#1 rdf:singletonPropertyOf :mentions .
:mentions#1 :times 5 .
请注意,您可以为 :mentions#1 属性使用任何名称以避免冲突。请查看上面链接的 sildeshare 以获取更多示例和 SPARQL 用法
最后但并非最不重要的一种非标准方式,仅由 BigData AFAIK 支持,是正确具体化, or RDR。使用 RDR 你可以写
<<:Susan :mentions :Bob>> :times 5
通过添加双尖括号,您可以添加关于语句的语句。这也适用于大数据 SPARQL 处理器。