RDF可以使用边缘属性为带标签的属性图建模吗?

时间:2019-04-28 00:11:43

标签: rdf graph-databases gremlin amazon-neptune

我想像以下那样建立合作伙伴关系模型,我用标记的属性图的格式表示。

enter image description here

我想使用RDF语言来表达上面的图形,特别是我想了解是否可以表达“ loves”边缘的标签(这是文章/字母的URI)。

我是RDF的新手,我知道RDF可以轻松表达LPG中的节点属性,但是可以方便地表达边缘属性吗?

此问题的更多上下文:我想使用RDF(而不是Gremlin)的原因是,从长远来看,我想添加一些推理功能。

进一步补充的问题:如果我们选择用RDF模型来表示上述LPG,用简单的英语,我想用SPARQL查询回答以下问题:

  1. 鲍勃爱上任何一个人吗?
  2. 如果是这样,他爱上谁?为什么?

查询loveletters.com/123的SPARQL语句有多复杂?

2 个答案:

答案 0 :(得分:12)

RDF不支持边缘属性,因此简单的回答是“否” 。但是,当然有一些方法可以在RDF中为这种事情建模。

无边缘特性的普通RDF三元组

如果我们不想对边缘进行注释,则鲍勃和玛丽之间的关系将是三重关系,其中鲍勃为主体,玛丽为对象,“爱”为谓语:

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>.

因此,我们说有一个陈述,其中鲍勃为主语,玛丽为宾语,“爱”为谓语。然后,我们可以向该语句添加属性。缺点是它有点多余。首先,我们添加“爱”三元组,然后再添加四个三元组来复制“爱”三元组。

选项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或正确完成版本化。)RDF * / RDR添加了新语法,该语法允许三元组成为其他三元组的主题:

<<person:Bob :loves person:Mary>>
    :reason <http://loveletters.com/123>.

缺点是它是非标准的,到目前为止仅受少数系统(BlazegraphAnzoGraphan 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