Я пытаюсь реализовать мягкое удаление в Neo4j. График описан в Cypher с точки зрения Алисы как таковой:Neo4j: реализация мягкого удаления с необязательными отношениями
(clyde:User)<-[:FOLLOWS]-(alice:User)-[:LIKES]->(bob:User)
Вместо фактически удаления узла и его отношения, я
- меняет свою этикетку, так что больше не может рассматриваться непосредственно , то есть сбрасывая метку
User
и добавляя метку_User
(обратите внимание на подчеркивание) - , заменяя ее отношения, так что больше не могут быть достигнуты моими обычными запросами, например удаляя свои отношения
:FOLLOWS
и заменяя его отношениями:_FOLLOWS
.
Таким образом, это в основном эквивалент перемещения строки в таблицу архивации в реляционной базе данных. Я понял, что это довольно эффективный подход, потому что вы фактически никогда не посещаете части графика, которые были мягко удалены. Кроме того, вам не нужно изменять какие-либо ваши существующие запросы.
В результате мягкого удаления Алисы должно быть так:
(clyde:User)<-[:_FOLLOWS]-(alice:_User)-[:_LIKES]->(bob:User)
Моя первая попытка запроса была такова:
match (user:User {Id: 1})
optional match (user)-[follows:FOLLOWS]->(subject)
remove user:User set user:_User
delete follows
create (user)-[:_FOLLOWS]->(subject);
Проблема в том, что, когда этот пользователь не следует никому, запрос пытается создать взаимосвязь между user
и null
, потому что второе совпадение необязательно, поэтому оно дает мне эту ошибку: Other node is null.
Моя вторая попытка была такова:
match (user:User {Id: 1})
remove user:User set user:_User
optional match (user)-[follows:FOLLOWS]->(subject)
foreach (f in filter(f in collect({r: follows, n: subject}) where f.r is not null) | delete f.r create (user)-[:_FOLLOWS]->(f.n));
Так я кладу отношения и объекта в карте, собирая эти карты в коллекции, бросая все «пустые» карту прочь и перекручивание по коллекции. Но этот запрос дает мне эту ошибку:
SyntaxException: Invalid input '.': expected an identifier character, node labels, a property map, whitespace or ')' (line 1, column 238)
Кто-нибудь знает, как я могу это исправить?
Спасибо, Jan
Я думаю, что это работает, если между пользователями существует только один вид отношений, то есть только:: FOLLOWS. Но в моем случае на самом деле больше, например ': LIKES', которые также должны быть заменены. Если у пользователя нет, например, отношений ': FOLLOWS' и хотя бы одного отношения': LIKES', я не думаю, что могу нести пользователя. –
Не уверен, что вы имеете в виду. Ваш вопрос заключался в обработке нулевого случая из необязательного совпадения в вашем запросе («Проблема в том, что ...»), вот что я ответил. – jjaderberg
Конечно, я должен был быть более ясным. Я хочу иметь возможность заменить несколько типов отношений, как необязательных, так и обязательных. Ваше решение не работает, если у пользователя нет отношений: FOLLOWS, потому что он использует точное совпадение, и пользователю не нужно переносить на: часть LIKES, потому что она не соответствует в: части FOLLOWS. Именно поэтому я использовал опциональное совпадение в первую очередь, но это приводит к двум ошибкам в исходном вопросе. –