Я пытаюсь найти эффективный способ получить набор значений свойств для предков узла. Рассмотрим следующий тривиальный настройка:Получить набор значений свойств для всех предков
CREATE
(a {id:'a'}), (b {id:'b'}), (c {id:'c'}), (d {id:'d', age:10}),
(b)-[:HAS_PARENT]->(a),
(c)-[:HAS_PARENT]->(a),
(d)-[:HAS_PARENT]->(b),
(d)-[:HAS_PARENT]->(c)
Я хотел бы получить набор с идентификатором d
и все ид вдоль любого пути между d
и a
наряду с некоторыми другими свойствами d
.
Я придумал это:
MATCH (d {id:'d'})
OPTIONAL MATCH path=(d)-[:HAS_PARENT*]->()
RETURN d.age as age,
(REDUCE(o = [], r IN (collect (extract (n in nodes(path) | n.id))) | o + r)) AS closure
который не совсем работает, потому что не хранит значения в closure
уникальной и также кажется невероятно неэффективным. Если я уйду с этого согласования маршрута и вместо этого просто проецировать идентификатор d
, а затем выполнить одну и ту же обходе себя с Java API:
for (Path path: graphDb.traversalDescription()
.depthFirst()
.relationships(RealtionshipNames.HAS_PARENT, Direction.OUTGOING)
.uniqueness(Uniqueness.NODE_GLOBAL)
.traverse(graphDb.getNodeById(nodeId))) {
ids.add((String)path.endNode().getProperty("id"))
}
задача завершает в секундах, даже с моим большим набором данных (100k узлы, 200k отношения). С моим запросом Cypher он никогда не завершается.
Есть ли способ объединить это все в единый, эффективный запрос Cypher или мне лучше делать некоторую пост-обработку с помощью Java API?
Что именно должен вернуть запрос? Это ('d', ['b', 'a']) и ('d', ['c', 'a'])? Или ('d', ['b', 'c', 'a'])? Или что-то другое? – zaboco
@zaboco он должен вернуть набор ('d', 'c', 'b', 'a'). – condit