简体   繁体   中英

Neo4j query improvization

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 

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM