在Neo4j中,如何减轻家谱中的双向关系?

时间:2016-04-27 01:47:32

标签: neo4j cypher family-tree

我遇到了关于双向关系的问题。

假设我正在尝试创建代表家谱的图表。这里的问题是:
*蒂米可以是苏西的兄弟,但是 *苏西不能是蒂米的兄弟。

因此,有必要在两个方向上对此进行建模:

enter image description here

(当然,从技术上来说,我可以说SIBLING_TO并且只留下一个优势......当我尝试将奶奶连接到孙子时,我不确定词汇是什么。)

当这一切都说完了,我很确定在这个例子中方向很重要的事实是无法解决的。

关于常见的Neo4j错误,我正在阅读blog post。作者指出,这种双向性不是在Neo4j中建模数据的最有效方法,应该避免。

我开始同意了。我建立了一个由2个家庭组成的模拟集:
enter image description here 我发现我试图运行的很多查询都非常非常慢。这是因为图表的“全部连接到所有”性质,至少在每个相应的家庭中。

我的问题是:
1)我是否正确地说双向性不理想?

2)如果是这样,我的家族树的例子是否可以用任何其他方式表示......在我可能出现问题的许多情况下,什么是“最佳实践”?

3)如果不能以另一种方式表示族树,技术上是否仍然可以以某种方式编写查询以解决1)的问题?

感谢您阅读本文和您的想法。

2 个答案:

答案 0 :(得分:1)

在数据库中存储冗余信息(双向关系)绝不是一个好主意。这是表示家谱的更好方法。

要指出" siblingness",您只需要一种关系类型,比如说SIBLING_OF,您只需要在两个兄弟节点之间建立一个这样的关系。

要表示祖先,您只需要一种关系类型,比如CHILD_OF,您只需要在孩子与其每个父母之间建立一个这样的关系。

每个人都应该有一个节点标签,比如Person。每个人都应该有一个唯一的ID属性(比如id),以及某种表示性别的属性(比如布尔isMale)。

使用这个非常简单的数据模型,这里有一些示例查询:

  1. 找人123的姐妹(注意图案没有指明关系方向):

    MATCH (p:Person {id: 123})-[:SIBLING_OF]-(sister:Person {isMale: false})
    RETURN sister;
    
  2. 查找Person 123的祖父(请注意,此模式指定匹配路径的深度必须为2):

    MATCH (p:Person {id: 123})-[:CHILD_OF*2..2]->(gf:Person {isMale: true})
    RETURN gf;
    
  3. 找人123的曾孙:

    MATCH (p:Person {id: 123})<-[:CHILD_OF*3..3]-(ggc:Person)
    RETURN ggc;
    
  4. 找人123的母亲叔叔:

    MATCH (p:Person {id: 123})-[:CHILD_OF]->(:Person {isMale: false})-[:SIBLING_OF]-(maternalUncle:Person {isMale: true})
    RETURN maternalUncle;
    

答案 1 :(得分:0)

我不确定您是否知道可以双向查询(即忽略方向)。所以你可以这样做:

MATCH (a)-[:SIBLING_OF]-(b)

由于我没有匹配方向,因此它会兼顾两种方式。这就是我建议建模的方法。

一般来说,如果你真的想要存储不同的状态,你只想建立多个关系。例如,KNOWS关系只能应用一种方式,因为A人可能知道B,但B可能不知道A.同样,您可能与{property}有{value}属性显示A B,并且可能有不同的优势&#34;喜欢&#34;在两个方向