Neo4j MATCH затем MERGE слишком много попаданий в БД

Это запрос:

MATCH (n:Client{curp:'SOME_VALUE'}) 
WITH n 
MATCH (n)-[:HIZO]-()-[r:FB]-()-[:HIZO]-(m:Client) 
WHERE ID(n)<>ID(m)
AND NOT (m)-[:FB]->(n) 
MERGE (n)-[:FB]->(m) RETURN m.curp

ПРОФИЛЬ

Почему на этапе слияния получается так много обращений к БД, если запрос уже сузил n, m пар до 6 781 строк?

Детали этого этапа показывают это:

n, m, r
(n)-[ UNNAMED155:FB]->(m)

1 ответ

Решение

Имейте в виду, что запросы формируют строки, и операции в вашем запросе выполняются на каждой построенной строке.

Поскольку шаблон в вашем совпадении может найти несколько путей к одному и тому же клиенту, он будет создавать несколько строк с одинаковыми n и m (но, возможно, с разными r, но, поскольку вы не используете r в другом месте в своем запросе, я призываю вам удалить переменную).

Это означает, что даже если вы хотите MERGE единственную связь между n и отдельным m, эта операция MERGE будет фактически выполняться для каждой повторяющейся строки n и m. Один из этих MERGE будет создавать отношения, другие будут тратить циклы, соответствующие отношениям, которые были созданы, не делая ничего больше.

Вот почему мы должны быть в состоянии снизить наши попадания в дб, рассматривая только отдельные пары n и m перед выполнением MERGE.

Кроме того, так как ваш запрос убедился, что мы рассматриваем только n и m, где отношения не существуют, мы можем безопасно использовать CREATE вместо MERGE, и это должно сэкономить нам несколько ударов в db, потому что MERGE всегда сначала пытается выполнить MATCH, что не не нужно

Улучшенный запрос может выглядеть так:

MATCH (n:Client{curp:'SOME_VALUE'}) 
WITH n 
MATCH (n)-[:HIZO]-()-[:FB]-()-[:HIZO]-(m:Client) 
WHERE n <> m
AND NOT (m)-[:FB]->(n) 
WITH DISTINCT n, m
MERGE (n)-[:FB]->(m) 
RETURN m.curp

РЕДАКТИРОВАТЬ

Возврат запроса для использования MERGE для отношения:FB, поскольку попытки использовать CREATE вместо этого закончились неудачей.

Другие вопросы по тегам