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

che*_*hen 8 rdf graph-databases gremlin amazon-neptune

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

在此处输入图片说明

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

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

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

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

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

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

cyg*_*gri 14

RDF doesn't support edge properties, so the brief answer is no. But of course there are ways to model this kind of thing in RDF.

Plain RDF triple without edge properties

If we didn't want to annotate the edge, the relationship between Bob and Mary would simply be a triple with Bob as Subject, Mary as object, and “loves” as predicate:

PREFIX : <http://example.org/ontology#>
PREFIX person: <http://example.org/data/person/>

person:Bob :loves person:Mary.
Run Code Online (Sandbox Code Playgroud)

So how can we add annotations?

Option 1: Using RDF Reification

RDF has a built-in solution called “RDF reification”. It allows making statements about statements:

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>.
Run Code Online (Sandbox Code Playgroud)

So we say that there is a statement with Bob as subject, Mary as object, and “loves” as predicate. Then we can add properties to that statement. The downside is that it is kind of redundant. First we add the “loves” triple, then we add four more triples to replicate the “loves” triple.

Option 2: Modelling relationships as entities

Another approach is to change the model. Instead of considering “loves” an edge between people, we consider it a node in itself. A node that represents the relationship, and is connected to the two parties involved.

PREFIX relationship: <http://example.org/data/relationship/>

relationship:1 a :LovesRelationship;
    :who person:Bob;
    :whom person:Mary;
    :reason <http://loveletters.com/123>.
Run Code Online (Sandbox Code Playgroud)

So in our model we created a class :LovesRelationship that represents “loves”, and properties :who and :whom to indicate the two parties. The downside of this approach is that the graph structure no longer directly represents our social network. So when querying how two people are related, we always have to go through those relationship entities instead of just dealing with edges connecting people.

Option 3: Using RDF*

There is a proposal called RDF* that addresses this problem quite nicely. (Sometimes it's called RDR or Reification Done Right.) RDF*/RDR adds new syntax that allows triples to be the subject of other triples:

<<person:Bob :loves person:Mary>>
    :reason <http://loveletters.com/123>.
Run Code Online (Sandbox Code Playgroud)

The downside is that it is non-standard and so far supported only by a few systems (Blazegraph, AnzoGraph, and an extension for Jena). As of April 2019, Neptune is not among them.

Query: Is Bob in love with anyone?

This is easy to do in the basic RDF version as well as in Option 1 and Option 3:

ASK { person:Bob :loves ?anyone }
Run Code Online (Sandbox Code Playgroud)

Option 2 requires a different query, because of the changed model:

ASK {
   ?rel a :LovesRelationship;
       :who person:Bob.
}
Run Code Online (Sandbox Code Playgroud)

This would match any :LovesRelationship where the :who property is Bob, regardless of the :whom and :reason properties.

Query: Who is Bob in love with and why?

Option 1, RDF Reification:

SELECT ?whom ?why {
    ?statement a rdf:Statement;
        rdf:subject person:Bob;
        rdf:predicate :loves;
        rdf:object ?whom;
        :reason ?why.
}
Run Code Online (Sandbox Code Playgroud)

I find this query not very intuitive, because it talks about RDF statements, while we are really interested in people and relationships.

Option 2, relationship modelled as entity:

SELECT ?whom ?why {
    ?rel a :LovesRelationship;
        :who person:Bob;
        :whom ?whom;
        :reason ?why.
}
Run Code Online (Sandbox Code Playgroud)

This is better in my eyes; once you have accepted that relationships are entities in this model, it becomes fairly intuitive.

Option 3, RDF*, using SPARQL*:

SELECT ?whom ?why {
    <<person:Bob :loves ?whom>>
        :reason ?why.
}
Run Code Online (Sandbox Code Playgroud)

This is concise and intuitive, so it's a shame we can't currently use it in most SPARQL systems!