3

我正在尝试在 Neo4j 中实现软删除。从 Alice 的角度来看,Cypher 中描述的图形是这样的:

(clyde:User)<-[:FOLLOWS]-(alice:User)-[:LIKES]->(bob:User)

而不是实际删除一个节点及其关系,我

  1. 更改其标签,使其不再可以直接查找,即删除其User标签并添加_User标签(注意下划线)
  2. 替换它的关系,这样我的正常查询就不能再访问它了,例如删除它的: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);

问题是当这个用户没有关注任何人时,查询会尝试在和之间创建关系usernull因为第二个匹配是可选的,所以它给了我这个错误: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)

有谁知道我该如何解决这个问题?

谢谢,扬

4

1 回答 1

3

你能先改变标签,然后匹配关系吗?那么您应该能够使用“非可选”匹配,而不必处理没有跟随关系的情况,例如

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)不起作用)

您正在寻找类似的东西还是我误解了您的问题?

于 2013-12-16T09:44:11.173 回答