Graph Neo4j/Cypher-查找具有2个以上链接的连接节点

Graph Neo4j/Cypher-查找具有2个以上链接的连接节点,graph,neo4j,cypher,Graph,Neo4j,Cypher,我有一个如下的图表(为了简单起见,删除了任何标签或链接方向) 我想从节点(c)开始,只找到那些有两条以上相邻边的节点,以及从(c)到它们的路径 在上面的示例中,节点(b)有3条相邻边(b-a、b-c、b-g),节点(e)有4条相邻边(e-d、e-f、e-h、e-h),因此我只想返回到(b)和(e)的路径 我也不想返回(a)、(f)、(h)、(g)或(j)的路径-我想在满足计数时停止遍历 我尝试了以下方法: START n=node(c) MATCH (n)-[r*]-(m)-[rx]-(o)

我有一个如下的图表(为了简单起见,删除了任何标签或链接方向)

我想从节点(c)开始,只找到那些有两条以上相邻边的节点,以及从(c)到它们的路径

在上面的示例中,节点(b)有3条相邻边(b-a、b-c、b-g),节点(e)有4条相邻边(e-d、e-f、e-h、e-h),因此我只想返回到(b)和(e)的路径

我也不想返回(a)、(f)、(h)、(g)或(j)的路径-我想在满足计数时停止遍历

我尝试了以下方法:

START n=node(c)
MATCH (n)-[r*]-(m)-[rx]-(o)
WITH m AS m, n AS n, r AS r, count(rx) as cnt
WHERE cnt > 2
RETURN n, r, m, cnt;
。。。但它除了返回b和e外,还返回到a、g、h、f和j的路径。对于一个大的图形来说,这也是非常昂贵的

非常感谢您的帮助

编辑:

我提供的示例图像过于简化了我的数据,因此最初的建议不起作用(请参阅),因此下面提供了一个新的图像示例

我想要:仅指向e和b的路径-与以前一样

我不想返回h的路径


再次感谢neo4jers…

有意思的一个,我已经使用将其放入Neo4j控制台

您要查找的Cypher声明是:

START n=node(2) // node c has node id = 2
MATCH p=(n)-[KNOWS*]-(m),(m)-[:KNOWS]-(x)
WITH p, count(x) AS count
WHERE count>2
RETURN p

这里的技巧是在
匹配中分两部分指定路径。然后,第一部分用于使用
WITH
进行聚合,对于
返回

有趣的部分,我使用将其放入Neo4j控制台

您要查找的Cypher声明是:

START n=node(2) // node c has node id = 2
MATCH p=(n)-[KNOWS*]-(m),(m)-[:KNOWS]-(x)
WITH p, count(x) AS count
WHERE count>2
RETURN p

这里的技巧是在
匹配中分两部分指定路径。然后,第一部分用于使用
WITH
进行聚合,并用于
返回

基于Stefans的建议来查看遍历框架,我花了一段时间试图在python(neo4j rest客户端)中找到它。以下代码段现在可以工作了:

# Retrieve the node at the start of the traveral
seed_node = gdb.nodes(node_id)

# Establish what the traversal should look like
simpleTraversalTemplate = traversals.TraversalDescription().relationships('adjacent')

# Set some un-chainable attributes - work breadth first and set max depth of traversal
simpleTraversalTemplate.breadthFirst()

# This is how far you think it will go before meeting a junction. 100 is high.
simpleTraversalTemplate.max_depth(100)

# Set up a prune evaluator. This by itself (without the filter evaluator)
# returns all traversals up to the point where the link count is > 2. This includes
# the traversals to the nodes before the >2 link_count node. 
simpleTraversalTemplate.prune(value={'body':"parseInt(position.endNode().getProperty('link_count')) > 2;",
                                     'language':'javascript'})

# So, a filter is used with the prune to only return those traversals where the end node link_count 
# is >2. With only this (ie without prune), the traversal would continue and just keep returning
# those nodes with link_count > 2. 
simpleTraversalTemplate.filter(value={'body':"parseInt(position.endNode().getProperty('link_count')) > 2;",
                                     'language':'javascript'})

# Now run the traverser based on the seed node
trav = simpleTraversalTemplate.traverse(seed_node)

根据Stefans关于查看遍历框架的建议,我花了一段时间试图在python(neo4j rest客户端)中找到它。以下代码段现在可以工作了:

# Retrieve the node at the start of the traveral
seed_node = gdb.nodes(node_id)

# Establish what the traversal should look like
simpleTraversalTemplate = traversals.TraversalDescription().relationships('adjacent')

# Set some un-chainable attributes - work breadth first and set max depth of traversal
simpleTraversalTemplate.breadthFirst()

# This is how far you think it will go before meeting a junction. 100 is high.
simpleTraversalTemplate.max_depth(100)

# Set up a prune evaluator. This by itself (without the filter evaluator)
# returns all traversals up to the point where the link count is > 2. This includes
# the traversals to the nodes before the >2 link_count node. 
simpleTraversalTemplate.prune(value={'body':"parseInt(position.endNode().getProperty('link_count')) > 2;",
                                     'language':'javascript'})

# So, a filter is used with the prune to only return those traversals where the end node link_count 
# is >2. With only this (ie without prune), the traversal would continue and just keep returning
# those nodes with link_count > 2. 
simpleTraversalTemplate.filter(value={'body':"parseInt(position.endNode().getProperty('link_count')) > 2;",
                                     'language':'javascript'})

# Now run the traverser based on the seed node
trav = simpleTraversalTemplate.traverse(seed_node)

惊人-感谢Stefan的快速响应!我也很高兴为Neo4j控制台贡献了一些东西(如果只是一个问题的话)。好吧,看来我的示例太简单了,查询对我的数据集不起作用,因为我过于简化了。实际的图形要深得多,因此您的查询并不像我希望的那样执行。这里有一个更准确的表示(现在我已经了解了neo4j控制台是什么):您可能应该限制深度,而不是使用例如[KNOWS*.10]`或任何对您的域合理的东西。使用Java traversal API可以更有效地实现此查询。是的,我考虑了深度限制,但是链接>2的节点可以位于任何深度。只有两个以上的链接才能使它们与众不同。同意遍历,这感觉是正确的解决方案-我使用的是python neo4jrestclient,遍历文档看起来有点单薄。反向方法的性能如何<代码>将n-[r]与n匹配,将(r)计算为cnt,其中cnt>4匹配n-(n2{Id:2})返回n
惊人-感谢Stefan的快速响应!我也很高兴为Neo4j控制台贡献了一些东西(如果只是一个问题的话)。好吧,看来我的示例太简单了,查询对我的数据集不起作用,因为我过于简化了。实际的图形要深得多,因此您的查询并不像我希望的那样执行。这里有一个更准确的表示(现在我已经了解了neo4j控制台是什么):您可能应该限制深度,而不是使用例如[KNOWS*.10]`或任何对您的域合理的东西。使用Java traversal API可以更有效地实现此查询。是的,我考虑了深度限制,但是链接>2的节点可以位于任何深度。只有两个以上的链接才能使它们与众不同。同意遍历,这感觉是正确的解决方案-我使用的是python neo4jrestclient,遍历文档看起来有点单薄。反向方法的性能如何<代码>将n-[r]与n匹配,将(r)计数为cnt,其中cnt>4匹配n--(n2{Id:2})返回n