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

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

问题描述

我正在尝试在Neo4j中实现软删除.从爱丽丝的角度来看,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.

软删除爱丽丝的结果应为:

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之间创建关系,因为第二个匹配项是可选的,因此它给了我这个错误:Other node is null.

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.

我的第二次尝试是

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)

或者您可以随身携带用户,关注对象和主题,并在主题不为null的地方进行过滤.像

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.

由于您无法动态建立关系类型(即CREATE (a)-[newRel:"_"+type(oldRel)]->(b)不起作用),我不认为在cypher中有一种通用的方法

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天全站免登陆