Я использовал cypher и neo4j какое-то время, и я снова и снова сталкиваюсь с подобной проблемой.
Я хотел бы иметь возможность добавить временное свойство к node, которое существует только в возвращаемых данных и не сохраняется в базе данных Neo4j.
Например, текущая проблема, над которой я работаю, дается N-арная древовидная структура в базе данных графа, я хотел бы вернуть детей определенного node, и информационное логическое значение, дающее мне знать, что у этих детей есть дети.
Запрос на получение этой информации достаточно прост:
MATCH (parent:Item { guid: "Identifier here" })-[:HASCHILD]->(child:Item)
OPTIONAL MATCH (child)-[:HASCHILD]->(grandchild:Item)
WITH parent, child, LENGTH(COLLECT(grandchild)) > 0 AS has_children
Теперь у меня есть родительский, дочерний и логический, дающий мне знать, что есть еще дети.
То, что я хотел бы сделать дальше, - установить has_children boolean как свойство на дочерних узлах, но только для возврата запроса мне не нужно, чтобы свойство сохранялось.
Я знаю, что есть некоторые решения, чтобы получить то, что я ищу, но ни один из них не является тем, что я ищу.
1) Я мог бы создать временный node: (Продолжение из предыдущего запроса)
...
WITH parent, child, LENGTH(COLLECT(grandchild)) > 0 AS haschildren,
{
childkey1: child.childkey1,
childkey2: child.childkey2,
...
has_children: haschildren
} AS tempnode
RETURN parent, tempnode
Это решение не очень велико, вам нужно знать точный тип node и все свойства node, с которыми вы имеете дело, он не будет работать в общем случае.
2) Я мог бы УСТАНОВИТЬ и УДАЛИТЬ логическое, временно сохраняя его в базе данных (как описано в Neo4J создать временную переменную в Cypher).
Это не очень удобно, так как это приведет к многократной записи db (для добавления и удаления). Кроме того, он не так динамичен, как вариант 1, поскольку он сможет обрабатывать только простые типы. (Вариант 1 может обрабатывать более сложные случаи, такие как добавление коллекции узлов вместо простого логического).
Насколько я знаю, это единственные варианты, когда речь заходит о временных данных возврата. Мне интересно, я что-то упустил? Можно ли сделать это более простым или динамичным?
Что-то вдоль линий
WITH parent, child, LENGTH(COLLECT(grandchild)) > 0 AS haschildren,
TEMPSET child.has_children = haschildren
Обратите внимание, что я немного упростил приведенные примеры. Я столкнулся с этой проблемой несколько раз в разных контекстах в neo4j. В большинстве случаев я либо иду с вариантом 1, либо строю правильную структуру после обработки на стороне приложения после возвращения запроса.
Есть ли лучший способ?