RDF 不支持边缘属性,因此简短的回答是否定的。但是当然有一些方法可以在 RDF 中对这类事物进行建模。
没有边缘属性的普通 RDF 三元组
如果我们不想标注边,Bob 和 Mary 之间的关系将只是一个三元组,其中 Bob 作为主语,Mary 作为宾语,“loves”作为谓词:
PREFIX : <http://example.org/ontology#>
PREFIX person: <http://example.org/data/person/>
person:Bob :loves person:Mary.
那么我们如何添加注解呢?
选项 1:使用 RDF 实体化
RDF 有一个称为“RDF 物化”的内置解决方案。它允许对语句进行语句:
PREFIX : <http://example.org/ontology#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX person: <http://example.org/data/person/>
PREFIX statement: <http://example.org/data/statement/>
person:Bob :loves person:Mary.
statement:1 a rdf:Statement;
rdf:subject person:Bob;
rdf:predicate :loves;
rdf:object person:Mary;
:reason <http://loveletters.com/123>.
所以我们说有一个以 Bob 作为主语、Mary 作为宾语、“loves”作为谓语的语句。然后我们可以向该语句添加属性。缺点是有点多余。首先我们添加“loves”三元组,然后再添加四个三元组来复制“loves”三元组。
选项 2:将关系建模为实体
另一种方法是更改模型。我们不认为“爱”是人与人之间的边缘,而是认为它本身就是一个节点。表示关系的节点,并连接到所涉及的两方。
PREFIX relationship: <http://example.org/data/relationship/>
relationship:1 a :LovesRelationship;
:who person:Bob;
:whom person:Mary;
:reason <http://loveletters.com/123>.
因此,在我们的模型中,我们创建了一个代表“爱”的类 :LovesRelationship,并创建了属性 :who 和 :whom 来表示两方。这种方法的缺点是图结构不再直接代表我们的社交网络。所以在查询两个人的关系时,我们总是要遍历那些关系实体,而不是仅仅处理连接人的边。
选项 3:使用 RDF*
a proposal called RDF* 很好地解决了这个问题。 (有时它被称为 RDR 或 Reification Done Right。)RDF*/RDR 添加了新语法,允许三元组成为其他三元组的主题:
<<person:Bob :loves person:Mary>>
:reason <http://loveletters.com/123>.
缺点是它是非标准的,到目前为止只有少数系统支持(Blazegraph、AnzoGraph 和 an extension for Jena)。截至 2019 年 4 月,海王星不在其中。
查询:Bob 是否爱上了任何人?
这在基本 RDF 版本以及选项 1 和选项 3 中很容易做到:
ASK { person:Bob :loves ?anyone }
选项 2 需要不同的查询,因为模型已更改:
ASK {
?rel a :LovesRelationship;
:who person:Bob.
}
这将匹配 :who 属性为 Bob 的任何 :LovesRelationship,无论 :whom 和 :reason 属性如何。
查询:Bob 爱上了谁,为什么?
选项 1,RDF 具体化:
SELECT ?whom ?why {
?statement a rdf:Statement;
rdf:subject person:Bob;
rdf:predicate :loves;
rdf:object ?whom;
:reason ?why.
}
我发现这个查询不是很直观,因为它讨论的是 RDF 语句,而我们对人和关系真的很感兴趣。
选项2,关系建模为实体:
SELECT ?whom ?why {
?rel a :LovesRelationship;
:who person:Bob;
:whom ?whom;
:reason ?why.
}
这在我看来更好;一旦您接受了关系是此模型中的实体,它就会变得相当直观。
选项 3,RDF*,使用 SPARQL*:
SELECT ?whom ?why {
<<person:Bob :loves ?whom>>
:reason ?why.
}
这是简洁直观的,遗憾的是我们目前无法在大多数 SPARQL 系统中使用它!