#neo4j #cypher #query-optimization
#neo4j #cypher #оптимизация запроса
Вопрос:
[Править / править код] Я использую Neo4j 4.2.1
Мне нужен запрос Cypher, который возвращает полное дерево с учетом его корневого узла. Все узлы и связи должны быть выбраны и представлены только один раз в возвращаемых наборах. Вот к чему я пришел:
MATCH p = (n)-[*..]->(m)
WHERE id(n) = 0
WITH relationships(p) AS r
WITH distinct last(r) as rel
WITH [node IN [startNode(rel), endNode(rel)] | node] AS tmp, rel
UNWIND tmp AS node
RETURN collect(DISTINCT node) AS nodes, collect(distinct rel) AS relationships;
Выполнение запроса в нашей базе данных для получения около 820 узлов приводит к сбою из-за нехватки памяти (разрешено 5 ГБ). Трудно поверить. Итак, мне интересно: является ли этот запрос ошибочным? Есть ли какой-либо метод, который я использую, который не следует использовать для моих целей?
Комментарии:
1. Есть ли свойство узла, которое гарантированно будет одинаковым для всех узлов в непрерывном дереве? Кроме того, вы уверены, что вам нужно вернуть все узлы и все отношения? Обычно вы возвращаете определенные фрагменты данных, что часто быстрее.
2. Нет свойства «помечать» для фильтрации узлов, принадлежащих дереву, если в этом смысл вашего вопроса. Цель состоит в том, чтобы слепо сбрасывать все дерево и иметь все свойства для каждого узла и отношения, чтобы дерево можно было повторно импортировать «как есть» в другую базу данных. Он работает довольно хорошо, но со временем могут возникнуть проблемы с объемом памяти. Кроме того, время выполнения здесь действительно не является проблемой.
3. Если вы просто хотите скопировать базу данных, перейдите в neo4j/data и скопируйте папки /databases/neo4j и /transactions/neo4j .
4. Моя цель — не копировать всю базу данных. В этом суть. Данные, о которых я беспокоюсь, организованы как набор «небольших» независимых деревьев. Почему я хочу выбрать дерево, по одному, по идентификатору его корня.
5. Хорошо, хорошо, примите мой ответ и измените
WHERE
предложение, чтобы получить только тех родителей, которых вы хотите (просто сделайте пути длиной 1). Сохраните все данные, необходимые для переконструирования узлов; вам также может понадобиться дополнительная информация для получения связей. Поместите все это в файлы значений, разделенные табуляцией, затем используйте возможность импорта CSV для переноса данных в новую базу данных.
Ответ №1:
Я настоятельно рекомендую вам придумать свойство node, которое гарантированно будет одинаковым для всех узлов в непрерывном дереве, если у вас его еще нет. Я назову это свойство same_prop
. Вот что я делаю для выполнения запросов, подобных тому, который вы выполняете:
- Указатель
same_prop
. Если у вас разные метки узлов, вам нужно, чтобы этот индекс создавался для каждой отдельной метки узла, которую вы ожидаете иметь в дереве.CREATE INDEX samepropnode FOR (n:your_label) ON (n.same_prop)
это то, что вам нужно в Neo4j 4 . В Neo4j индексы дешевы и иногда могут немного ускорить запросы. - Соберите все возможные значения
same_prop
и сохраните их в текстовом файле (я использую значения, разделенные табуляцией, как более безопасные, чем значения, разделенные запятыми). - Используйте драйвер Python или выбранный вами язык, на котором написан драйвер Neo4j (настоятельно рекомендую драйверы, предоставляемые Neo4j, а не сторонние), чтобы написать код-оболочку, который выполняет запрос Cypher примерно так:
MATCH (p)-->(c)
USING INDEX p:your_label(same_prop)
WHERE p.same_prop IN [ same_prop_list ]
RETURN DISTINCT
p.datapiece1 AS `first_parent_datapiece`,
p.datapiecen AS `nth_parent_datapiece`,
c.datapiece1 AS `first_child_datapiece`,
c.datapiecen AS `nth_child_datapiece`
В общем, не стоит возвращать узлы и отношения, если вы не отлаживаете.
Затем в вашем коде на Python (например) вы просто прочитаете все свои same_prop
значения из файла, который вы получили на шаге 2, разделите значения на порции разумного размера, возможно, 1000 или 10000, и замените их [ same_prop_list ]
на запрос in the Cypher на лету.
Комментарии:
1. «В общем, не очень хорошая идея возвращать узлы и отношения, если вы не отлаживаете». Хотя я склонен согласиться, я бы сказал, при всем моем уважении, что всегда полезно использовать правильные средства для достижения ваших целей. В моем случае я хочу пересадить полное дерево данных в новый сад базы данных.