Как получить доступ к объектам узла в коллекции путей? (пути двух или более узлов) - PullRequest
2 голосов
/ 20 июня 2019

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

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

match (o:Order{id:123})
match (o)-[:STATUS_CHANGE*]->(l:Log)-[:STATUS]->(os:OrderStatus)

with collect((l:Log)-[:STATUS]->(os:OrderStatus)) as logs

Я хочу получить доступ к каждому из узлов в путях, чтобы выполнить сравнение. Обычно для каждого Ордена 5 или 6 из (l) - [: STATUS] -> (os).

Как я могу получить доступ к узлам (l) и (os) каждого пути, чтобы выполнить сравнения между их свойствами?

Например, если бы у меня была эта коллекция путей в одном из Орденов:

scenario1

(log1) - [: STATUS] -> (os1)

(log2) - [: STATUS] -> (os2)

(log3) - [: STATUS] -> (OS3)

(log4) - [: STATUS] -> (os2) <- это ошибка </p>

(log5) - [: STATUS] -> (OS4)

Итак, из вышеупомянутой коллекции путей я бы хотел отменить удаление (log4), поскольку узел (os2) ниже предыдущего (os3) и должен быть больше.

И после этого я хочу прикрепить (log3) к (log5)


ПРИМЕЧАНИЕ. Каждый из узлов (os) имеет идентификатор, представляющий «статус», и имеет значение от 1 до 5. Кроме того, узлы (log) упорядочены по созданному дате и времени.


Есть идеи, как это сделать? Заранее спасибо, ребята!



EDIT

Я не упомянул некоторые другие сценарии, которые у меня были. Это один из них:

scenario 2

Основываясь на ответе @cybersam, я узнал, как это сделать.

Мне пришлось выполнить 2 отдельных запроса, чтобы заставить его работать, но принцип тот же и следующий:

Создание новых отношений:

MATCH(o:Order)-[:STATUS_CHANGE*]->(l:Log)-[:STATUS]->(os:OrderStatus)
WHERE SIZE((o)-[:STATUS_CHANGE*]->()-[:STATUS]->(os)) >= 1
WITH o, os, COLLECT(l)[0] AS keep
WITH o, collect(keep) AS k
FOREACH(i IN range(0,size(k)-1)   | 
FOREACH(a IN [k[i]]               | 
FOREACH(b IN [k[i+1]]             | 
FOREACH(c IN CASE WHEN b IS NOT NULL THEN [1] END | MERGE (a)-[:STATUS_CHANGE]->(b) ))));

Удалить превышенные узлы:

MATCH(o:Order)-[:STATUS_CHANGE*]->(l:Log)-[:STATUS]->(os:OrderStatus)
WHERE (os)<-[:STATUS]-()-[:STATUS_CHANGE*]->(l)-[:STATUS]->(os)
WITH o, os, COLLECT(l) AS exceed
UNWIND exceed AS del
detach delete del;

Этот запрос работал для каждого сценария.

1 Ответ

2 голосов
/ 20 июня 2019

Если все ваши ошибки следуют одному и тому же шаблону (нежелательные Log узлы всегда ссылаются на "более старый" OrderStatus), это может работать для вас:

MATCH (o:Order{id:123})-[:STATUS_CHANGE*]->(l:Log)-[:STATUS]->(os:OrderStatus)
WHERE SIZE(()-[:STATUS]->(os)) > 1
WITH os, COLLECT(l) AS logs
UNWIND logs[1..] AS unwanted
OPTIONAL MATCH (x)-[:STATUS_CHANGE]->(unwanted)-[:STATUS_CHANGE]->(y)
DETACH DELETE unwanted
FOREACH(ignored IN CASE WHEN x IS NOT NULL THEN [1] END | CREATE (x)-[:STATUS_CHANGE]->(y))

Этот запрос:

  • Находит (по порядку) все соответствующие OrderStatus узлы, имеющие несколько STATUS взаимосвязей.
  • Использует функцию агрегирования COLLECT для сбора (по порядку)Log узлы, связанные с каждым из этих OrderStatus узлов.
  • Использует UNWIND logs[1..] для получения отдельных нежелательных Log узлов.
  • Использует OPTIONAL MATCH для получения 2 узловкоторые, возможно, потребуется соединить вместе после удаления нежелательного узла.
  • Использует DETACH DELETE для удаления каждого нежелательного узла и его взаимосвязей.
  • Использует FOREACH для соединения парыузлы, которые могли быть найдены OPTIONAL MATCH.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...