Добавление фильтра свойств к запросу шифрования взрывает память, почему? - PullRequest
0 голосов
/ 19 апреля 2019

Я пытаюсь написать запрос, который исследует диаграмму типа DAG (ведомость материалов) для всех путей построения, ведущих к определенному номеру детали (второй MATCH), среди всех деталей, связанных с данным продуктом (Первый матч).Есть странное поведение, которого я не понимаю:

Этот запрос выполняется в разумные сроки, используя выпуск сообщества Neo4j (~ 2 с):

WITH '12345' as snid, 'ABCDE' as pid
MATCH (m:Product {full_sn:snid})-[:uses]->(p:Part)
WITH snid, pid, collect(p) AS mparts
MATCH path=(anc:Part)-[:has*]->(child:Part)
WHERE ALL(node IN nodes(path) WHERE node IN mparts)
WITH snid, path, relationships(path)[-1] AS rel, 
nodes(path)[-2] AS parent, nodes(path)[-1] AS child
RETURN stuff I want

Однако, чтобы получить запрос Iхочу, я должен добавить фильтр на дочерний элемент, используя pid номера детали во втором операторе MATCH:

MATCH path=(anc:Part)-[:has*]->(child:Part {pn:pid})

И когда я пытаюсь выполнить новый запрос, браузер neo4j обнаруживает, что недостаточно памяти.(Neo.TransientError.General.OutOfMemoryError).Когда я запускаю его с EXPLAIN, попадания в БД взрываются до десятков миллиардов, как будто я прошу у него массивный картезианский продукт: но все, что я сделал, это добавил ограничение на ребенка, так что это должно уменьшитьпространство для поиска, не так ли?

Я также попытался добавить индекс для: Part (pn).Теперь профиль, показанный EXPLAIN, выглядит очень эффективно, но у меня все та же ошибка памяти.

Если кто-нибудь может помочь мне понять, почему это изменение между двумя запросами вызывает проблемы, я был бы очень признателен!

С наилучшими пожеланиями,

Бен

1 Ответ

0 голосов
/ 19 апреля 2019
MATCH path=(anc:Part)-[:has*]->(child:Part)

* взрывается для каждого нижестоящего дочернего узла.Это уместно, если это то, что нужно.Если вы сделаете это необязательным совпадением и ограничением для элементов сбора, это должно ограничить возвращаемые результаты.

   OPTIONAL MATCH path=(anc:Part)-[:has*]->(child:Part)

Это концептуально (и грубо) похоже на внутреннее соединение в SQL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...