Импровизация запросов Neo4j - PullRequest
1 голос
/ 18 июня 2020

Как я могу оптимизировать запрос ниже

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 

1 Ответ

0 голосов
/ 18 июня 2020

Это может сработать для вас:

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) 

Кроме того, если допустимо сделать шаблон отношения -[:AFFINITY*..4]- направленным (путем размещения стрелки на одном конце), тогда запрос должен быть еще быстрее .

[ОБНОВЛЕНИЕ]

Основываясь на ваших комментариях, ниже я предполагаю, что шаблон отношения изменен на направленный и используется уменьшенная верхняя граница 3. Чтобы получить результат, более близкий к ваши исходные результаты:

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) 

Этот запрос возвращает результаты для самых длинных путей, которые не превышают границы.

...