Оптимизировать запрос на шифрование, чтобы избежать декартового произведения.

Цель запроса довольно тривиальна. Для заданного nodeId(userId) я хочу вернуть на графике все узлы, которые имеют связь в пределах X прыжков, и я хочу агрегировать и вернуть расстояние (параметр, который устанавливается для отношения) между ними)

Я придумал это:

MATCH p=shortestPath((user:FOLLOWERS{userId:{1}})-[r:follow]-(f:FOLLOWERS)) " +
                        "WHERE f <> user " +
                        "RETURN (f.userId) as userId," +                     
                        "reduce(s = '', rel IN r | s + rel.dist + ',') as dist," +
                        "length(r) as hop"

ИД пользователя ({1}) указан как входной и индексируется.

Я верю, что у меня есть здесь декартово произведение. как бы вы предложили избегать этого?

1 ответ

Решение

Вы можете сделать декартово произведение менее обременительным, создав индекс на :FOLLOWERS(userId) чтобы ускорить одну из двух "ножек" декартового произведения:

CREATE INDEX ON :FOLLOWERS(userId);

Даже если это не избавит от декартового произведения, оно будет работать за O(N log N), что намного быстрее, чем O(N ^ 2).

Кстати, ваш r Чтобы ваш запрос работал, отношения должны быть переменной длины. Вы должны указать разумную верхнюю границу (которая зависит от вашей БД), чтобы гарантировать, что запрос завершится в разумные сроки и не исчерпает память. Например:

MATCH p=shortestPath((user:FOLLOWERS { userId: 1 })-[r:follow*..5]-(f:FOLLOWERS))
WHERE f <> user
RETURN (f.userId) AS userId,
  REDUCE (s = '', rel IN r | s + rel.dist + ',') AS dist,
  LENGTH(r) AS hop;
Другие вопросы по тегам