Как создать отношения между похожими / параллельными путями в neo4j? - PullRequest
0 голосов
/ 05 октября 2018

Я ищу способ пакетного создания отношений между похожими / параллельными путями в neo4j.

Пример графика может выглядеть следующим образом:

enter image description here

Как видите, розовый узел (тот, что в центре):WRAPS 3 желтых узла, и каждый желтый узел :WRAPS 2 красных узла.Я пытаюсь создать 3 :PARALLEL отношения между каждой возможной парой из 3 узлов.Я попробовал этот оператор Cypher:

MATCH (pink:Slide)-[:WRAPS]->(yellow:GroupBox)-[:WRAPS*]->(red:Content)
WHERE pink.uuid = "ca7e1d47-1fbe-4008-9617-ef41c8a04316"
MATCH path = (yellow)-[rel]->(red)
RETURN path

Возвращает все желтые узлы и связанные красные узлы.График выглядит следующим образом:

enter image description here

Однако, поскольку класс пути Path, а не List, я не могу использовать размотку / foreachперебрать их.Я также пытался relationships(path), но он возвращает кучу пустых массивов.Я намерен сравнить длину и метки узлов в каждом пути, но не могу найти способ сделать это.Не могли бы вы помочь с этим?

1 Ответ

0 голосов
/ 05 октября 2018

Создание вашего графика

Для простоты возможных дальнейших ответов и решений, я отмечу мое утверждение создания графика:

CREATE
  // left bunch
  (pink:PinkNode {name: '369'})-[:WRAPS]->(yellow1:YellowNode {name: '190'}),
  (yellow1)-[:WRAPS]->(red1:RedNode {name: '201'}),
  (yellow1)-[:WRAPS]->(red2:RedNode {name: '198'}),
  (pink)-[:WRAPS]->(red1),
  (pink)-[:WRAPS]->(red2),

  // upper bunch
  (pink)-[:WRAPS]->(yellow2:YellowNode {name: '195'}),
  (yellow2)-[:WRAPS]->(red3:RedNode {name: '204'}),
  (yellow2)-[:WRAPS]->(red4:RedNode {name: '208'}),
  (pink)-[:WRAPS]->(red3),
  (pink)-[:WRAPS]->(red4),

  // lower bunch
  (pink)-[:WRAPS]->(yellow3:YellowNode {name: '192'}),
  (yellow3)-[:WRAPS]->(red5:RedNode {name: '208'}),
  (yellow3)-[:WRAPS]->(red6:RedNode {name: '210'}),
  (pink)-[:WRAPS]->(red5),
  (pink)-[:WRAPS]->(red6),

  // "free" red ones
  (pink)-[:WRAPS]->(red7:RedNode {name: '255'}),
  (pink)-[:WRAPS]->(red8:RedNode {name: '166'}),
  (pink)-[:WRAPS]->(red9:RedNode {name: '264'}),
  (pink)-[:WRAPS]->(red10:RedNode {name: '269'});

Решение

Все возможные отношения между вашими тремяПары узлов вы получите с помощью следующего оператора Cypher:

CALL apoc.periodic.COMMIT('
MATCH
  (pink:PinkNode)-[:WRAPS]->(yellow:YellowNode)-[:WRAPS]->(red:RedNode)
WITH yellow AS startNode, yellow AS endNode WHERE NOT (startNode)-[:PARALLEL]->(endNode) AND id(startNode) < id(endNode)
CREATE (startNode)-[:PARALLEL]->(endNode)
RETURN count(*)
', {limit: 10000});

Основная идея

Основываясь на идентификации и выборе ваших пар из трех узлов в строке 3, я проверяю в строке 4если желаемое :PARALLEL отношение уже существует.Если нет, я создаю его (строка 5).С помощью библиотеки APOC я выполняю этот оператор до тех пор, пока не будут созданы все отношения.

Специально для обработки графа полезно многократно выполнять запрос в отдельных транзакциях, пока он не будетт обрабатывает и генерирует какие-либо результаты больше.Таким образом, вы можете выполнять итерации в пакетах по элементам, которые не удовлетворяют условию, и обновлять их, чтобы они выполняли впоследствии.

Запрос выполняется многократно в отдельных транзакциях, пока не вернет 0.

( взято из индекса процедуры Neo4j APOC на GitHub )

Сравнение идентификаторов в строке 4 позволяет избежать наличия двух отношений на пару (по одному в каждом направлении) и предотвращает создание связи между узлами исами по себе.

...