在Neo4j中将箭头/关系建模为节点

在Neo4j中将箭头/关系建模为节点,neo4j,Neo4j,Neo4j中的关系/箭头不能获取多个类型/标签(请参阅和)。我有一个数据模型,边缘需要获得标签和(可能)属性。如果我决定使用Neo4j(而不是支持带标签的箭头的OriendDB),我想我会有两个选项来建模两个节点A和B之间的箭头,比如f: 1) 将箭头f编码为范围,例如AB,这样f也是一个节点-->和f-->B,这样f又是一个节点,两个-->是箭头 虽然这似乎增加了我的数据模型,但如果我想使用Neo4j,目前似乎没有其他选择。然后,我试图看看上面哪种编码可能更适合我的查询(查询是我的系统的核心)

Neo4j中的关系/箭头不能获取多个类型/标签(请参阅和)。我有一个数据模型,边缘需要获得标签和(可能)属性。如果我决定使用Neo4j(而不是支持带标签的箭头的OriendDB),我想我会有两个选项来建模两个节点A和B之间的箭头,比如f:

1) 将箭头f编码为范围,例如AB,这样f也是一个节点-->和f-->B,这样f又是一个节点,两个-->是箭头

虽然这似乎增加了我的数据模型,但如果我想使用Neo4j,目前似乎没有其他选择。然后,我试图看看上面哪种编码可能更适合我的查询(查询是我的系统的核心)。为此,我需要举一些例子。所以我有两个问题:

第一个问题:

第1部分)我有标记为Person和father的节点,它们之间有箭头,如
PersonPerson
以模拟谁是谁的父亲(tr是sr的父亲)。对于一个特定的人,我怎样才能得到他所有的祖先

part2)如果我使用
Person-[:sr]->father-[:tr]->Person
结构来建模父亲关系,那么上述相同的查询将是什么样子

当父亲被认为是一个简单的关系(而不是被编码为一个节点)时,这就得到了回答

第二个问题:

第1部分)我将节点标记为A节点,每个节点的属性为p1。我想查询一个节点,获取那些p1isA-[:tr]>qa1替代的元素


当isA被认为是一个简单的箭头(而不是被建模为节点)时,这个问题就得到了回答。

首先,一些术语;关系没有标签,只有类型。是的,每个关系有一种类型

其次,相对于建模,我认为关系的方向并不总是非常重要,因为使用neo4j,您可以轻松地双向遍历它。因此,我认为
A-->f-->B
AB
之间的差异应该完全取决于对您的域在语义上有意义的内容,而不是其他内容。因此,就整体复杂性而言,我认为你在顶部的选项(1)和(2)是相同的,这让我想到了第3点:

您的主要选择是将一个复杂的关系创建为一个节点(我认为这里我们称之为
f
),还是将其作为一个关系保存。将“关系转换为节点”被称为,我认为这被认为是一种相当标准的实践,以适应许多建模问题。它确实增加了复杂性(相对于简单的关系),但增加了灵活性。这是一个相当标准的工程权衡

这么说吧,对于你的第一个问题,我不推荐中间节点<代码>:父亲是一种非常简单的关系,我不明白为什么你需要一个以上的标签。所以对于第一个问题,我会选择“你列出的两个选项中的任何一个”,并将其建模为
(personA)-[:father]>(personB)
。更简单。你可以这样问

   MATCH (personA { name: "Bob"})-[:father]->(bobsDad) RETURN bobsDad
是的,您可以将其建模为
(personA)-[:sr]>(父权)-[:tr]>(personB)
,但我看不出这对您有多大好处。至于关系的方向,这同样与性能或查询无关,只与
:tr
:sr
的语义有关

我将节点标记为节点,每个节点的属性为p1。我想要 要查询节点,请获取p1isA-[:tr]->qa1的元素

修改上面的查询应该很简单,只需更改箭头的方向,相同的查询。

我把
(personA)-[:father]->(personB)
作为一个示例,看看如果我具体化所有箭头,传递闭包查询会是什么样子。所以你是对的,在这个具体的例子中,我没有得到任何额外的分数。
MATCH (aNode:A)
WHERE aNode.p1 < 5
WITH aNode
MATCH (qa1 { label: "some qa1 node" })
CREATE (qa1)<-[:sr]-(isA)-[:tr]->aNode;