Graph Neo4j/Cypher-查找具有2个以上链接的连接节点
我有一个如下的图表(为了简单起见,删除了任何标签或链接方向) 我想从节点(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)的路径-我想在满足计数时停止遍历 我尝试了以下方法: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)
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