我正在尝试在Neo4j中实现软删除。从爱丽丝的观点来看Cypher中描述的图表是这样的:
(clyde:User)<-[:FOLLOWS]-(alice:User)-[:LIKES]->(bob:User)
我没有实际删除节点及其关系,而是
User
标签并添加_User
标签(请注意下划线):FOLLOWS
关系并将其替换为:_FOLLOWS
关系。因此,这基本上相当于将行移动到关系数据库中的归档表。我认为这是一种非常有效的方法,因为您实际上从未访问过已被软删除的图形部分。此外,您不必修改任何现有查询。
软删除Alice的结果应该是:
(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
之间创建关系,因为第二个匹配是可选的,因此它会给我这个错误:{{ 1}}
我的第二次尝试是:
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));
有谁知道如何解决这个问题?
谢谢, 扬
答案 0 :(得分:2)
您可以先更改标签然后匹配关系吗?那么你应该能够使用'非可选'匹配,而不必处理没有以下关系的情况,比如
MATCH (user:User {Id: 1})
REMOVE user:User SET user:_User
WITH user
MATCH (user)-[follows:FOLLOWS]->(subject)
DELETE follows
CREATE (user)-[:_FOLLOWS]->(subject)
或者您可以随身携带用户,跟随并主题并过滤主题不为空的位置。像
这样的东西MATCH (user:User {Id: 1})
OPTIONAL MATCH (user)-[follows:FOLLOWS]->(subject)
REMOVE user:User SET user:_User
WITH user, follows, subject
WHERE subject IS NOT NULL
DELETE follows
CREATE (user)-[:_FOLLOWS]->(subject)
修改强>
如果问题是您想要为多种关系执行此操作,那么您可以尝试
MATCH (user:User {Id: 1})
REMOVE user:User SET user:_User
WITH user
MATCH (user)-[f:FOLLOWS]->(other)
DELETE f
CREATE (user)-[:_FOLLOWS]->(other)
WITH user LIMIT 1
MATCH (user)-[l:LIKES]->(other)
DELETE l
CREATE user-[:_LIKES]->(other)
您可以继续使用其他关系类型进行扩展,只需确保在携带时限制user
,因为多个匹配(user)-[r]->(other)
表示用户有多个结果,或者您将运行下一个多次查询部分。
我不认为在cypher中有一种通用的方法,因为你无法动态构建关系类型(即CREATE (a)-[newRel:"_"+type(oldRel)]->(b)
不起作用)
这就是你想要的东西,还是我误解了你的问题?