Neo4j:使用可选关系实现软删除 [英] Neo4j: implementing soft delete with optional relationships

查看:23
本文介绍了Neo4j:使用可选关系实现软删除的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to implement a soft delete in Neo4j. The graph described in Cypher from Alice's viewpoint is as such:

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

我没有实际删除节点及其关系,而是

Instead of actually deleting a node and its relationships, I'm

  1. 改变它的标签,使其不再被直接查找,即删除它的 User 标签并添加一个 _User 标签(注意下划线)
  2. 替换其关系,以便我的正常查询无法再访问它,例如删除其 :FOLLOWS 关系并将其替换为 :_FOLLOWS 关系.
  1. changing its label so it can no longer be looked up directly, i.e. dropping its User label and adding a _User label (notice the underscore)
  2. replacing its relationships so it can't be reached anymore by my normal queries, e.g. deleting its :FOLLOWS relationships and replacing it with :_FOLLOWS relationships.

所以这基本上相当于将行移动到关系数据库中的归档表.我认为这是一种非常有效的方法,因为您实际上从未访问过已被软删除的图形部分.此外,您无需修改​​任何现有查询.

So this is basically the equivalent of moving a row to an archiving table in a relational database. I figured this is a pretty efficient approach because you're effectively never visiting the parts of the graph that have been soft-deleted. Also, you don't have to modify any of your existing queries.

软删除Alice的结果应该是这样的:

The result of soft-deleting Alice should be this:

(clyde:User)<-[:_FOLLOWS]-(alice:_User)-[:_LIKES]->(bob:User)

我第一次尝试查询是这样的:

My first attempt at the query was this:

match (user:User {Id: 1})
optional match (user)-[follows:FOLLOWS]->(subject)
remove user:User set user:_User
delete follows
create (user)-[:_FOLLOWS]->(subject);

问题是当这个用户没有关注任何人时,查询会尝试在 usernull 之间创建关系,因为第二个匹配是可选的,所以它给出我这个错误:其他节点为空.

The problem is that when this user is not following anyone, the query tries to create a relationship between user and null because the second match is optional, so it gives me this error: Other node is null.

我的第二次尝试是这样的:

My second attempt was this:

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));

所以我将关系和主题放入一张地图中,将这些地图收集到一个集合中,丢弃所有空"地图并循环遍历该集合.但是这个查询给了我这个错误:

So I'm putting the relationship and the subject into a map, collecting these maps in a collection, throwing every "empty" map away and looping over the collection. But this query gives me this error:

SyntaxException: Invalid input '.': expected an identifier character, node labels, a property map, whitespace or ')' (line 1, column 238)

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

Does anyone know how I can fix this?

谢谢,扬

推荐答案

能否先更改标签,然后再匹配关系?那么你应该能够使用非可选"匹配,而不必处理没有跟随关系的情况,比如

Could you change the label first and then match for relationships? Then you should be able to use 'non-optional' match, and not have to deal with the cases where there are no follows relationships, something like

MATCH (user:User {Id: 1})
REMOVE user:User SET user:_User
WITH user
MATCH (user)-[follows:FOLLOWS]->(subject)
DELETE follows
CREATE (user)-[:_FOLLOWS]->(subject)

或者你可以携带用户,关注和主题,并过滤主题不为空的地方.类似的东西

Or you could carry the user, follows and subject and filter on where subject is not null. Something like

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)


如果问题是你想为不止一种关系这样做,那么你可以尝试


If the problem is that you want to do this for more than one kind of relationship, then you could try

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) 表示用户有多个结果,否则您将多次运行下一个查询部分.

You can keep extending it with other relationship types, just be sure to limit user when you carry, since multiple matches (user)-[r]->(other) means there are multiple results for user, or you'll run the next query part multiple times.

我认为在 cypher 中没有通用的方法可以做到这一点,因为您无法动态构建关系类型(即 CREATE (a)-[newRel:"_"+type(oldRel)]->(b) 不起作用)

I don't think there is a generic way to do it in cypher since you can't dynamically build the relationship type (i.e. CREATE (a)-[newRel:"_"+type(oldRel)]->(b) doesn't work)

这是否是您要查找的内容,还是我误解了您的问题?

Is something like that what you are looking for or am I misunderstanding your question?

这篇关于Neo4j:使用可选关系实现软删除的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆