我想像以下那样建立合作伙伴关系模型,我用标记的属性图的格式表示。
我想使用RDF语言来表达上面的图形,特别是我想了解是否可以表达“ loves”边缘的标签(这是文章/字母的URI)。
我是RDF的新手,我知道RDF可以轻松表达LPG中的节点属性,但是可以方便地表达边缘属性吗?
此问题的更多上下文:我想使用RDF(而不是Gremlin)的原因是,从长远来看,我想添加一些推理功能。
进一步补充的问题:如果我们选择用RDF模型来表示上述LPG,用简单的英语,我想用SPARQL查询回答以下问题:
查询loveletters.com/123
的SPARQL语句有多复杂?
答案 0 :(得分:12)
RDF不支持边缘属性,因此简单的回答是“否” 。但是,当然有一些方法可以在RDF中为这种事情建模。
如果我们不想对边缘进行注释,则鲍勃和玛丽之间的关系将是三重关系,其中鲍勃为主体,玛丽为对象,“爱”为谓语:
PREFIX : <http://example.org/ontology#>
PREFIX person: <http://example.org/data/person/>
person:Bob :loves person:Mary.
那么我们如何添加注释?
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>.
因此,我们说有一个陈述,其中鲍勃为主语,玛丽为宾语,“爱”为谓语。然后,我们可以向该语句添加属性。缺点是它有点多余。首先,我们添加“爱”三元组,然后再添加四个三元组来复制“爱”三元组。
另一种方法是更改模型。我们没有将``爱''视为人与人之间的优势,而是将其视为自身的一个节点。表示关系的节点,并连接到所涉及的双方。
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
来表示两方。这种方法的缺点是图结构不再直接代表我们的社交网络。因此,在查询两个人之间的关系时,我们总是必须遍历这些关系实体,而不仅仅是处理连接人的边缘。
有a proposal called RDF*很好地解决了这个问题。 (有时将其称为RDR或正确完成版本化。)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系统中使用它!
答案 1 :(得分:0)
AnzoGraph支持RDF * / SPARQL *,因此您实际上可以使用简洁,最直观的格式表示数据并进行查询。
insert data {
:Bob a :Person; <name> "Bob"; <state> "CA" .
:Mary a :Person; <name> "Mary"; <state> "CA" .
:Bob <loves> :Mary .
<< :Bob <loves> :Mary >> <reason> <http://loveletters.com/123> .
}
现在查询:
select ?who ?whom ?reason
where {
?p1 a :Person ; <name> ?who .
?p2 a :Person ; <name> ?whom .
<< ?p1 <loves> ?p2 >> <reason> ?reason .
}
结果:
who | whom | reason
-----+------+----------------------------
Bob | Mary | http://loveletters.com/123
1 rows