理论上,RDF图是一个三元组集合,这意味着每个三元组只能出现一次。当然,你可以有一个文档,比如Turtle格式,其中包含重复的三元组或四元组,但在加载到内存/存储后,这些三元组应该被视为一个。毕竟,任何文档都只是文本。
话虽如此,我看到了不同的行为取决于三元组存储。例如,AllegroGraph默认加载和处理重复的三元组。有一个手动选项来修剪重复项。
而且,查询不会告诉你是否有重复的问题,因为SPARQL聚合是使用节点而不是整个三元组工作的。
关于你的例子,有多种方法。
TL/DR 你需要一种添加关于语句的语句的方式。请参阅
this slideshare,其中包含各种方法,以下是我简要描述的一些方法。
完整回答
最简单的方法是引入某种人工中介图节点,可以称为
Mention或其他名称。例如:
:Susan :mentions [
rdf:type :Mention ;
:mentionsWhom :Bob ;
:times 5
]
问题在于,如果您将这样的结构引入现有数据,则会破坏现有的语义。
一个简单且广泛支持的方法是使用
命名图,这样你就有了
四元组而不是三元组。下面的例子增强了turtle语法,使其成为
TriG。请注意,命名图只是另一个资源。使用任何SPARQL处理器也很容易查询命名图。
:susanMentionsBob {
:Susan :mentions :Bob
}
:susanMentionsBob :times 5
另一个传统的解决方案是使用某种形式的具体化。通过具体化,您可以创建一个rdf:Statement对象,在其中添加其他数据。缺点是您需要重复原始三元组s/p/o
:Susan :mentions :Bob .
_:reifiedStatement
rdf:type rdf:Statement ;
rdf:subject :Susan ;
rdf:predicate :mentions ;
rdf:object :Bob ;
:times 5 .
最近引入了更简洁的实体化方式。您可以使用
单例属性代替。您需要引入一个额外的谓词,用于替换单个使用的
:mentions,并向该属性添加附加语句:
:Susan :mentions
:mentions
:mentions
请注意,您可以使用任何名称来 :mentions#1 属性,以避免冲突。请查看上面链接的 sildeshare 了解更多示例和 SPARQL 用法。
最后介绍一种非标准的方式,据我所知仅由BigData支持,即
Reification Done Right或RDR。使用RDR,您可以编写:
<<:Susan :mentions :Bob>> :times 5
通过添加双尖括号,您可以添加关于语句的语句。这在BigData的SPARQL处理器中也适用。