Neo4j 如何从某个起始节点递归删除节点

标签 neo4j cypher spring-data-neo4j graph-databases

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

@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 然后我需要递归删除所有子 由这些节点定义的产品CriteriaVotesUser 节点不得删除

我试过这个 Cypher 查询:

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

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

最佳答案

我会把它分成两个查询。第一个递归向下收集产品层次结构,第二个删除一个产品节点及其直接环境。

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

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

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

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

我没有自己测试这个查询,因为你没有提供测试图。因此,将此作为一个想法并对其进行修改,直到它起作用。

更新

在聊天中我们发现这个密码语句解决了问题,请注意 Product 已被替换为模型中的 Decision 标签:

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 如何从某个起始节点递归删除节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29714877/

相关文章:

neo4j - Janusgraph 功能和 future

neo4j - 从 Neo4j Cypher allShortestPaths() 中排除包含给定节点或给定关系的路径

java - 使用 Spring 数据存储库加载 Neo4j 嵌套关系

testing - Spring Data Neo4j 4.0.0.M1 测试配置

graph - 如何使用 gremlin 在 titan 图形数据库中查找 clique?

grails - 如何将Javascript变量发送到Grails Controller 以查询Neo4J

neo4j - 如何在图形数据库中对客户调查进行建模?

neo4j - Neo4j 数据库、NestJS 框架和 GraphQL 如何集成?

docker - 如何在Cypher Neo4j中合并多个WITH和MATCH子句

java - Node 不会持久化到 Neo4j