How to avoid cycle in neo4j cypher queries

孤街浪徒 提交于 2019-12-24 18:25:10

问题


I have friend-friend data model which has two relationships between any two friend nodes based on how one friend defines the other friend. For example, User "A" can define user "B" as 'FRIEND' and "B" can define "A" as 'BUDDY'. The problems is, when I try to get the 3rd degree of relationship of user "A", it returns user "B", where as the actual result should be "D" only.

MATCH(a:Users {first_name : "A"}) -[:BUDDY|FRIEND*3] -> (b)
RETURN a,b

OR

MATCH (a)-[]-(b)-[]-(c)-[]-(d)
WHERE a.first_name="A" 
RETURN a,d


回答1:


Alternatively, you can do this:

MATCH p=((a:Users {first_name : "A"})-[:BUDDY|FRIEND*3]->(b))
WITH DISTINCT a, b, nodes(p) as nodes
UNWIND nodes AS node
WITH a, b, nodes, COLLECT(DISTINCT node) as distinct_nodes
WITH a, b WHERE SIZE(nodes)=SIZE(distinct_nodes)
RETURN a, b

or a bit easier with an APOC call:

MATCH p=((a:Users {first_name : "A"})-[:BUDDY|FRIEND*3]->(b))
WITH DISTINCT a, b WHERE SIZE(nodes(p)) = SIZE(apoc.coll.toSet(nodes(p)))
RETURN a, b



回答2:


I'd suggest the APOC Path Expander procedures which use a means of expansion that only ever consider a single path to a node, allow for specification of the max and min depth, take relationship filters, and set whether visiting a node more than once is permitted. Specifically, the apoc.path.expandConfig() procedure should meet your needs.

MATCH (a:Users {first_name: "A"})
CALL apoc.path.expandConfig(a, {relationshipFilter:"BUDDY|FRIEND",minLevel:3,maxLevel:3, bfs:true,uniqueness:"NODE_GLOBAL"}) YIELD path
RETURN a, path

The uniqueness:"NODE_GLOBAL" parameter makes sure no node is visited more than once.



来源:https://stackoverflow.com/questions/59371986/how-to-avoid-cycle-in-neo4j-cypher-queries

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!