Neo4j如何从某个起始节点递归删除节点 [英] Neo4j how to delete nodes recursively from some start node

查看:232
本文介绍了Neo4j如何从某个起始节点递归删除节点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的Neo4j数据库中,我具有以下实体:

In my Neo4j database I have a following entities:

@NodeEntity
public class Product {

    private final static String CONTAINS = "CONTAINS";
    private final static String DEFINED_BY = "DEFINED_BY";
    private final static String VOTED_FOR = "VOTED_FOR";
    private final static String PARENT = "PARENT";
    private final static String CREATED_BY = "CREATED_BY";

    @GraphId
    private Long id;

    @RelatedTo(type = PARENT, direction = Direction.INCOMING)
    private Product parent;

    @RelatedTo(type = CONTAINS, direction = Direction.OUTGOING)
    private Set<Product> childProducts = new HashSet<>();

    @RelatedTo(type = DEFINED_BY, direction = Direction.INCOMING)
    private Set<Criterion> criterias = new HashSet<>();

    @RelatedTo(type = VOTED_FOR, direction = Direction.INCOMING)
    private Set<Vote> votes = new HashSet<>();

    @RelatedTo(type = CREATED_BY, direction = Direction.OUTGOING)
    private User user;

}    

@NodeEntity
public class Criterion {

    private final static String CREATED_BY = "CREATED_BY";
    private final static String DEFINED_BY = "DEFINED_BY";

    @GraphId
    private Long id;

    @RelatedTo(type = DEFINED_BY, direction = Direction.OUTGOING)
    private Product owner;

    @RelatedTo(type = CREATED_BY, direction = Direction.OUTGOING)
    private User user;

}

@NodeEntity
public class Vote {

    private static final String VOTED_ON = "VOTED_ON";
    private final static String VOTED_FOR = "VOTED_FOR";
    private static final String CREATED_BY = "CREATED_BY";

    @GraphId
    private Long id;

    @RelatedTo(type = VOTED_FOR, direction = Direction.OUTGOING)
    private Product product;

    @RelatedTo(type = VOTED_ON, direction = Direction.OUTGOING)
    private Criterion criterion;

    @RelatedTo(type = CREATED_BY, direction = Direction.OUTGOING)
    private User user;

}

Product是一个复合实体,可以包含子Products. 从层次结构中的某些Product节点开始,我需要删除此Product上的所有Votes,然后需要递归删除这些节点和Votes定义的所有子级ProductsCriteria. User节点不能删除.

Product is a composite entity and can contain child Products. Starting from some Product node in the hierarchy I need to delete all Votes on this Product and then I need to recursively delete all child Products, Criteria defined by these nodes and Votes. User nodes must not be deleted.

我已经尝试过以下Cypher查询:

I have tried this Cypher query:

MATCH (p:Product)-[r:CONTAINS*]-(e) WHERE id(p) = {productId} FOREACH (rel IN r| DELETE rel) DELETE e 

,但它仅删除产品,并且不会删除起始节点上的投票以及所有子级条件和投票.请帮助我进行正确的Cypher查询.谢谢.

but it deletes only Products and doesn't delete Votes on the start node and all child Criteria and Votes. Please help me with a correct Cypher query. Thanks.

推荐答案

我将其分为两个查询.第一个递归地向下收集产品层次结构,第二个递归地删除一个产品节点及其直接环境.

I'd split that up into two queries. The first one recursively collects the the product hierarchy downwards and the second one deletes one product node and its direct environment.

获取产品层次结构很简单:

Getting the product hierarchy is simple:

MATCH (p:Product)-[:CONTAINS*]->(childProduct)
WHERE id(p) = {productId}
RETURN id(childProduct) as id

要删除一个产品,我们需要删除该产品节点的所有关系.此外,如果所有相关节点都不是用户(您想保留它们)或产品(想想父产品-也应该保留它们),则也需要删除.此外,我们还需要确保目标节点未连接,这就是第二个可选匹配项的原因:

To delete one product we need to delete all relationships of that product node. Additionally all related nodes need to be deleted as well if they are neither user (you want to keep them) or products (think of parent products - they should be kept as well). Also we need to be sure the target nodes are not connected, thats's why the 2nd optional match:

MATCH (p:Product) 
OPTIONAL MATCH (p)-[r]-(t)
WHERE id(p) = {productId}
DELETE r,p
WITH t
OPTIONAL MATCH (t)-[r2:VOTE_ON|:CREATED_BY]->()
WHERE none(x in labels(t) WHERE x in ["User", "Product"])
DELETE t,r2

由于您未提供测试图,因此我没有亲自测试此查询.因此,请以此为构思并对其进行修改,直到它起作用为止.

I did not test this query myself since you didn't provide a test graph. So take this as an idea and modify it until it works.

在聊天中我们发现此cypher语句解决了该问题,请注意,模型中Product已由Decision标签替换:

In a chat we found that this cypher statement solves the problem, note that Product has been replaced by Decision label in the model:

MATCH (p:Decision) 
WHERE p.name = "NoSQL" 
WITH p 
OPTIONAL MATCH (p)-[r]-(t) 
DELETE p,r 
WITH t,r 
OPTIONAL MATCH (t)-[r2:VOTED_ON|:CREATED_BY|:VOTED_FOR]-() 
WITH t, r2,r 
WHERE none(x in labels(t) WHERE x in ["User", "Decision"]) 
DELETE t,r2

这篇关于Neo4j如何从某个起始节点递归删除节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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