Насколько оптимизирован этот шифровальный запрос?

#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 . Вот что я делаю для выполнения запросов, подобных тому, который вы выполняете:

  1. Указатель same_prop . Если у вас разные метки узлов, вам нужно, чтобы этот индекс создавался для каждой отдельной метки узла, которую вы ожидаете иметь в дереве. CREATE INDEX samepropnode FOR (n:your_label) ON (n.same_prop) это то, что вам нужно в Neo4j 4 . В Neo4j индексы дешевы и иногда могут немного ускорить запросы.
  2. Соберите все возможные значения same_prop и сохраните их в текстовом файле (я использую значения, разделенные табуляцией, как более безопасные, чем значения, разделенные запятыми).
  3. Используйте драйвер 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. «В общем, не очень хорошая идея возвращать узлы и отношения, если вы не отлаживаете». Хотя я склонен согласиться, я бы сказал, при всем моем уважении, что всегда полезно использовать правильные средства для достижения ваших целей. В моем случае я хочу пересадить полное дерево данных в новый сад базы данных.