使用neo4j找到与给定节点有关系的节点集的有效方法
给定两个节点是否有一种有效的方法来查找一组公共节点(具有已定义的关系)。
例如,让节点A1
, B1
, C1
– C4
与关系x
和y
连接:
A1 --x--> C1 A1 --x--> C2 A1 --x--> C3 B1 --y--> C2 B1 --y--> C3 B1 --y--> C4
为A1(x)
和B1(y)
设置的公共节点将是[C2, C3]
。
在许多情况下,可以利用域的结构来提高性能。 假设您知道,一般而言,与B
实体上的y
关系数相比,您的A
实体具有更少的x
关系。 然后,您可以从A节点遍历两个步骤,并查看B
节点显示的位置,并以这种方式过滤掉C
节点。 以下是此方法的一些代码:
Set found = new HashSet (); for ( Relationship firstRel : a1.getRelationships( Reltypes.x, Direction.OUTGOING ) ) { Node cNode = firstRel.getEndNode(); for ( Relationship secondRel : cNode.getRelationships( Reltypes.y, Direction.INCOMING ) ) { Node bNode = secondRel.getStartNode(); if ( bNode.equals( b1 ) ) { found.add( cNode ); break; } } }
另一种方法是启动从两侧扫描关系的两个线程。
第三种方法是创建一个专门的索引来帮助回答这种查询,这显然会损害插入性能。
在Gremlin( http://gremlin.tinkerpop.com )中,这表达如下:
setA._().out('x').in('y').retain(setB).back(2)
以下是每个步骤的作用:
- 从setA开始(在您的示例中为A1,A2,A3)。
- 启动Gremlin管道。
- 将那些setA顶点的输出“x”标记边缘取为C1,C2和C3。
- 从C1,C2和C3中取出传入的“y”标记边。
- 过滤掉不在setB中的所有步骤(因此,只存在C2和C3路径)。
- 回到你之前看到的2步 – 因此,C2和C3。
田田!
祝你好运,马可。