Имеется база данных neo4j, содержащая вершины типа папок или листов.Общее дерево моделируется с использованием отношений childof, и существует один «корневой» узел, который является общим предком для всех вершин.
При представлении дерева я хочу отфильтровать полные ветви на основеидентификатор любой вершины типа папка.Дополнительно есть фильтр для любых свойств на вершинах типа лист.Сложность в том, что я не хочу видеть папки, в которых отфильтрованы все нисходящие конечные узлы.Каждый запрос возвращает только непосредственных потомков, но фильтр применяется ко всему поддереву.Запрос должен возвращать непосредственные дочерние элементы и коллекцию идентификаторов каждой папки, содержащей листы, которые не отфильтрованы.
Вариант использования - это API для отображения иерархии, основанной на некоторых ограничениях фильтра.Я запрограммировал это в коде приложения API, но передача всех данных из базы данных в приложение API выполняется слишком медленно, поэтому мне нужно улучшить запрос, чтобы сжать передачу данных.Третий подход - использование специально созданного процесса, который выполняет эту фильтрацию, сохраняя дерево в памяти.Это было сделано с некоторым успехом, но я предпочитаю использовать полки, если смогу.
Следующий код используется для получения узлов верхнего уровня без фильтрации.Я борюсь с выражением MATCH, только если хотя бы один потомок также соответствует
MATCH (p)-[:childof]->(s:Folder) WHERE s.name = 'root'
WITH p OPTIONAL MATCH (v)-[:childof*1..]->(p)
WHERE NOT((v)<-[:childof]-(:Folder))
RETURN p, collect(v.id) as folder_ids
Моя личная склонность к проблеме заключается в том, что он слишком специфичен для графического движка общего назначения, но я надеюсь, что он окажется неверным.