Reputation: 276
How can I Optimise below query
match (e1Server:Server) where e1Server.name='XYZ'
optional match (e1Server)-[r1:AFFINITY]-(n1Server:Server)
optional match (n1Server:Server)-[r2:AFFINITY]-(n2Server:Server) where id(e1Server) <> id(n2Server)
optional match (n2Server:Server)-[r3:AFFINITY]-(n3Server:Server) where id(e1Server) <> id(n3Server) and id(n1Server) <> id(n3Server)
optional match (n3Server:Server)-[r4:AFFINITY]-(n4Server:Server) where id(e1Server) <> id(n4Server) and id(n1Server) <> id(n4Server) and id(n2Server) <> id(n4Server)
return distinct e1Server,n1Server,n2Server,n3Server,n4Server
Upvotes: 1
Views: 52
Reputation: 67044
This may work for you:
MATCH p=(s:Server)-[:AFFINITY*..4]-(:Server)
WHERE
s.name = 'XYZ' AND
ALL(i IN RANGE(0, LENGTH(p)-1) WHERE
NONE(j IN RANGE(i+1, LENGTH(p)) WHERE NODES(p)[i] = NODES(p)[j]))
RETURN NODES(p)
Also, if it is valid to make the -[:AFFINITY*..4]-
relationship pattern directional (by putting an arrow on one end), then the query should be even faster.
[UPDATE]
Based on your comments, I will assume below that the relationship pattern is changed to be directional and to use a reduced upper bound of 3. To get a result closer to your original results:
MATCH p=(s1:Server)-[:AFFINITY*..3]->(s2:Server)
WHERE
s1.name = 'XYZ' AND
(LENGTH(p) = 3 OR NOT (s2)-[:AFFINITY]->(:Server)) AND
ALL(i IN RANGE(0, LENGTH(p)-1) WHERE
NONE(j IN RANGE(i+1, LENGTH(p)) WHERE NODES(p)[i] = NODES(p)[j]))
RETURN NODES(p)
This query returns results for the longest paths that do not exceed the bound.
Upvotes: 0