Neo4j Cypher - Условный с предложением запроса - PullRequest
0 голосов
/ 27 декабря 2018

Я пишу приведенный ниже запрос Neo4j Cypher, чтобы добавить новый Part и удалить старый Part из Vehicle узла.Я использую Neo4j (версия 3.4.1)

newParts и removedParts мои параметры.Это списки String.

with {newParts} AS newParts
unwind newParts as newPart
match (r:Vehicle) where id(r)=639
merge (r)-[:HAS_PART]->(np:Part{name:newPart})
on create np+={lastModifiedDateTime:localdatetime(), createdDateTime:localdatetime()}
with r optional match (r)-[rel:HAS_PART]-(p:Part) where p.name in {removedParts}
delete rel
with r match q=(r)--()
return nodes(q), relationships(q))

Это прекрасно работает, когда я предоставляю параметр newParts как непустой.

Однако, когда он пуст, я не получаю свой финалузлы и отношения.Я понимаю, почему это происходит, потому что разматывание останавливает выполнение, когда список пуст.Я попытался переместить with..unwind часть ниже del, и он успешно удаляет удаленные части Part.Однако он не возвращает конечные узлы и отношения, поскольку они появляются после размотки.

Я не уверен, как заставить это работать с пустым параметром newParts.Я пытался использовать case, но я думаю, case не работает с узлами и связями.

Любая помощь или указатели будут высоко оценены.

Заранее спасибо

V

Ответы [ 2 ]

0 голосов
/ 29 декабря 2018

Я смог найти ответ на свой вопрос благодаря совету и предложению администраторов Neo4j на слабом канале Neo4j.

Если вы хотите использовать простой запрос Cypher, вы можете использовать следующий ответ:

MATCH (r:Vehicle) WHERE id(r)=639
FOREACH(newPart IN {newParts}| 
MERGE (np:Part{id:newPart})
ON CREATE SET np+={partProperties}
MERGE (r)-[:HAS_PART]->(np))
WITH DISTINCT r SET r+={vehicleProperties} 
WITH DISTINCT r OPTIONAL MATCH p=(r)-[rel:HAS_PART]-(p:Part) where p.name in {removedParts} 
DELETE rel 
WITH DISTINCT r 
MATCH q=(r)--() 
RETURN q

Надеюсь, кто-то найдет это полезным!

С уважением, V

0 голосов
/ 28 декабря 2018

Идея

Вы можете использовать условное шифрование пользовательской библиотеки APOC в сочетании с непустой проверкой вашего параметра newParts.Пожалуйста, предпочтите apoc.do.when, а не apoc.when, поскольку оно выполняется в контексте чтения / записи, что необходимо для предложения MERGE.

Предлагаемое решение

WITH $newParts AS newParts, $removedParts AS removedParts
CALL apoc.do.when(
size($newParts) > 0,
// true case
'
  UNWIND newParts AS newPart
  MATCH (r:Vehicle) WHERE id(r)=639
  MERGE (r)-[:HAS_PART]->(np:Part{name:newPart})
  ON CREATE np+={lastModifiedDateTime:localdatetime(), createdDateTime:localdatetime()}
  RETURN r;
',
// false case
'
  UNWIND newParts AS newPart
  MATCH (r:Vehicle) WHERE id(r)=639
  RETURN r;
',
{newParts: newParts}) YIELD value AS result
WITH DISTINCT result.r AS r, removedParts
OPTIONAL MATCH (r)-[rel:HAS_PART]-(p:Part) WHERE p.name IN removedParts
DELETE rel
WITH DISTINCT r 
MATCH q=(r)--()
RETURN nodes(q), relationships(q);

Объяснение

  • строка 2: вызов конструкции if-then-else пользовательской библиотеки APOC
  • строка 3: условие для оценки, в этом случае проверка, не является ли параметр newParts не пустым
  • строка 5-11: секция if, которая передает Vehicle r
  • строка 13-17: секция else
  • строка 18: определениепараметр, который необходимо предоставить конструкции if-then-else и извлечь из нее результат
...