Добавить узел в связанный список после данного узла в шифре - PullRequest
0 голосов
/ 13 февраля 2020

У меня есть следующий график:

(Boxer)-[:STARTS]->(Round)-[:CONTINUES]->(Round)-[:CONTINUES]->(Round)-[:CONTINUES]->(Round)

Я хочу вставить новый раунд ПОСЛЕ указанного раунда с именем prevRound. Прямо сейчас я делаю это:

MERGE (round:Round {uuid: $round.uuid})
MERGE (prevRound:Round {uuid: $prevRound.uuid})
MERGE (prevRound)-[oldRel:CONTINUES]->(nextRound)
MERGE (prevRound)-[:CONTINUES]->(round)-[:CONTINUES]->(nextRound)
DELETE oldRel

Это работает, но на самом деле это создаст пустой узел, когда я попытаюсь вставить узел в конец списка. Я знаю, что это из-за:

MERGE (prevRound)-[oldRel:CONTINUES]->(nextRound)

Действительно, это создаст узел nextRound, когда он не существует.

Как я могу предотвратить это? Я попытался с дополнительным соответствием, но это не сработало хорошо.

1 Ответ

1 голос
/ 13 февраля 2020

MERGE не является правильным предложением для использования здесь, так как, как вы видели, он создаст шаблон, если он не существует, давая вам пустой узел и отношение к нему из prevRound. OPTIONAL MATCH - это правильное предложение, которое следует использовать для этой строки (хотя вам действительно нужно предложение WITH между ним и предыдущим MERGE) ... но на самом деле лучшим подходом будет немного изменить запрос (см. Последний абзац).

Вы также должны разделить последнее MERGE, так как более длинный паттерн, как этот, вероятно, не будет делать то, что вы ожидаете, что он будет делать при определенных обстоятельствах. Прочитайте нашу статью базы знаний о понимании того, как MERGE работает , чтобы узнать о некоторых тонких деталях, которые могли бы вас сбить с толку.

На самом деле мы можем sh выполнить то, что вам нужно, достаточно просто переставив детали вашего запроса.

MERGE (round:Round {uuid: $round.uuid})
MERGE (prevRound:Round {uuid: $prevRound.uuid})
WITH round, prevRound
OPTIONAL MATCH (prevRound)-[oldRel:CONTINUES]->(nextRound)
DELETE oldRel
MERGE (prevRound)-[:CONTINUES]->(round)
WITH round, nextRound, oldRel
WHERE nextRound IS NOT NULL
MERGE (round)-[:CONTINUES]->(nextRound)

Мы защищаем MERGE между round и nextRound с помощью предыдущего предложения WHERE, которое отфильтровывает все строки, где nextRound не существует.

Возможно, более простой способ сделать это, хотя и немного менее эффективно, - это работать с узлами, которые, как вы знаете, существуют вначале, округлять и превратить в круглые, а затем работать с шаблоном, который может существовать или не существовать, совпадать со старым узлом, хотя вам потребуется немного фильтрации, поскольку MATCH также выберет отношение, которое вы только что создали, для округления:

MERGE (round:Round {uuid: $round.uuid})
MERGE (prevRound:Round {uuid: $prevRound.uuid})
MERGE (prevRound)-[:CONTINUES]->(round)
WITH round, prevRound
MATCH (prevRound)-[oldRel:CONTINUES]->(nextRound)
WHERE nextRound <> round
DELETE oldRel
MERGE (round)-[:CONTINUES]->(nextRound)

Вы также можете подумать, есть ли места, где вы знаете, что таких отношений не существует, и если да, используйте CREATE вместо MERGE. У меня такое чувство, что последний MERGE здесь, вероятно, мог бы быть CREATE.

...