Sajeeva Lakmal
Sajeeva Lakmal

Reputation: 197

How to avoid cycle in neo4j cypher queries

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. enter image description here

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

enter image description here

Upvotes: 0

Views: 266

Answers (2)

julielinx
julielinx

Reputation: 128

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.

Upvotes: 1

NonameCurious
NonameCurious

Reputation: 606

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

Upvotes: 1

Related Questions