我想建模伙伴关系,如下所示,我用标签属性图的格式表示。
我想使用RDF语言来表达上面的图形,特别是我想了解我是否可以表达“loves”边缘的标签(这是文章/字母的URI)。
我是RDF的新手,我知道RDF可以很容易地表达LPG中的节点属性,但是可以方便地表达边缘属性吗?
这个问题的更多背景:我想要使用RDF(而不是Gremlin)的原因是我想从长远来看增加一些推理能力。
进一步补充的问题:如果我们选择一个RDF模型来表示上述LPG,用简单的英语,我想用SPARQL查询回答以下问题:
查询loveletters.com/123
的SPARQL语句有多复杂?
RDF不支持边缘属性,所以简单的答案是否定的。但是当然有办法在RDF中模拟这种事物。
如果我们不想注释边缘,那么鲍勃和玛丽之间的关系只会是鲍勃作为主题,玛丽作为对象,并且“喜欢”作为谓词的三重关系:
PREFIX : <http://example.org/ontology#>
PREFIX person: <http://example.org/data/person/>
person:Bob :loves person:Mary.
那么我们如何添加注释呢?
RDF有一个名为“RDF reification”的内置解决方案。它允许声明语句:
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>.
所以我们说有一个声明与鲍勃作为主题,玛丽作为对象,并“喜欢”作为谓词。然后我们可以为该语句添加属性。缺点是它有点多余。首先,我们添加“loves”三重奏,然后我们再添加四个三重奏来复制“loves”三重奏。
另一种方法是改变模型。我们不是考虑“喜欢”人与人之间的优势,而是将其视为一个节点。表示关系的节点,与所涉及的双方相连。
PREFIX relationship: <http://example.org/data/relationship/>
relationship:1 a :LovesRelationship;
:who person:Bob;
:whom person:Mary;
:reason <http://loveletters.com/123>.
所以在我们的模型中,我们创建了一个代表“loves”的类:LovesRelationship
,以及:who
和:whom
属性来表示两方。这种方法的缺点是图形结构不再直接代表我们的社交网络。因此,在查询两个人是如何相关时,我们总是必须经历这些关系实体,而不仅仅是处理连接人的边缘。
有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月,海王星不在其中。
这在基本的RDF版本以及选项1和选项3中很容易做到:
ASK { person:Bob :loves ?anyone }
选项2需要不同的查询,因为更改的模型:
ASK {
?rel a :LovesRelationship;
:who person:Bob.
}
这将匹配:LovesRelationship
属性为Bob的任何:who
,无论:whom
和:reason
属性如何。
选项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系统中使用它,这是一种遗憾!