【问题标题】:How to delete multiple nodes by specific ID using Cypher如何使用 Cypher 按特定 ID 删除多个节点
【发布时间】:2016-01-06 12:27:48
【问题描述】:

我正在尝试优化此密码查询。 我正在使用 neo4j-jdbc

对于给定的源节点和目标节点列表,我想删除它们之间的关系(“关注”)。

现在我只找到了一种在每个事务上执行它们的方法:

例如:

源节点:34 和目标节点:777

执行:

MATCH (p1:users)-[r:follow]->(p2:users)
WHERE p1.userId='34' and p2.userId='777' and
delete r

java neo4j-jdbc 代码:

 public void deleteNodes(String sourceUserId, Set<String> userIdsList) {
        try {
            conn = neo4jDataSource.openConnection();
            conn.setAutoCommit(false);
            newUserDistanceList.forEach(user -> {
                try {
                    this.deleteRelationship(sourceUserId, user.getUserId());
                } catch (SQLException e) {
                    throw new RuntimeException("Error deleting relationship for sourceNode=" + sourceUserId + ", targetNode=" + user.getUserId(), e);
                }
            });
            conn.commit();
        } catch (Exception e) {
            throw new RuntimeException("Error deleting relationship for sourceNode=" + sourceUserId, e);
        } finally {
            neo4jDataSource.closeConnection(conn);
        }
    }


 public void createNodeAndSetRelationship(String sourceUserId, String targetUserId) throws SQLException {
        String deleteUserStmnt =
 "MATCH (p1:users)-[r:follow]->(p2:users) "+
    "WHERE p1.userId=~{1} and p2.userId=~{2} and "+
    "delete r";            
        try (final PreparedStatement ps1 = conn.prepareStatement(deleteUserStmnt)) {
            ps1.setString(1, sourceUserId);
            ps1.setString(2, targetUserId);
            ps1.executeQuery();
        }
    }

您将如何将其优化为一个查询以包含所有内容?有可能吗?

*P.S 如果您觉得有帮助,请添加有关此代码的任何其他注释。

对 cme​​ts 的回应:

我以这种方式添加了我的节点:

MERGE (p1:C10{userId:'1'})
MERGE (p2:C10{userId:'2'})
MERGE (p3:C10{userId:'3'})
MERGE (p1)-[r1:follow]->(p2) 
MERGE (p1)-[t1:follow]->(p3)

执行删除查询时,不会删除任何内容:

MATCH (user1:C10 {userId: 1})-[r:follow]->(users:C10) WHERE
 users.userId in [3, 2] DELETE r
  • userId 是每个节点上的唯一属性

有什么想法吗?

谢谢你, 射线。

【问题讨论】:

    标签: jdbc neo4j cypher spring-data-neo4j


    【解决方案1】:

    查询

    让我们创建一些数据来测试我们的查询是否有效。

    CREATE (user1:User {id: "1"})
    CREATE (user2:User {id: "2"})
    CREATE (user3:User {id: "3"})
    CREATE (user1)-[:FOLLOW]->(user2)
    CREATE (user1)-[:FOLLOW]->(user3)
    

    我们的数据现在的样子:

    让我们编写查询来删除 user1 和 user2 和 user3 之间的:FOLLOW 关系:

    MATCH (user1:User {id: "1"})-[r:FOLLOW]->(users:User)
    WHERE users.id in ["2", "3"]
    DELETE r
    

    现在关系消失了:

    祝你好运:)

    注意:这也适用于字符串。
    注意2:您应该检查您的userId 是否存在index(或事件constraint) :user 节点上的属性。

    neo4j-jdbc

    neo4j-jdbc 的代码示例确实有效:

    Class.forName("org.neo4j.jdbc.Driver");
    Connection connection = DriverManager.getConnection("jdbc:neo4j://localhost:7474/");
    String removeRelationships = "MATCH (user1:User {id: {1}})-[r:FOLLOW]->(users:User) " +
            "WHERE users.id in {2} " +
            "DELETE r";
    try (final PreparedStatement stmt = connection.prepareStatement(removeRelationships)) {
        stmt.setObject(1, "1");
        stmt.setObject(2, new ArrayList<Integer>() {{
            add("2");
            add("3");
        }});
        stmt.executeQuery();
    }
    

    【讨论】:

    • 感谢您的详细回答。但是它没有用。我想通过 userId 删除用户,这是每个节点上的属性(它被索引为唯一)。我编辑了我的答案,请看一下
    • 在查询中将数字更改为字符串。例如,我使用了数字。在你的情况下 - WHERE users.id IN ['2', '3']
    • 而且查找也应该使用字符串 - MATCH (user1:C10 {userId: '1'}]
    • 在 cypher 上工作。但是你如何修改它以使用 neo4j-jdbc 语句工作?我切换到 List.. 但没有用: stmt.setObject(2, new ArrayList(){{ add("2"); add("3"); }});
    • 是的。它是 JDBC 适配器。适用于任何适配器的所有建议也适用于 Neo4j。
    猜你喜欢
    • 2015-03-24
    • 2012-07-30
    • 2022-12-21
    • 1970-01-01
    • 2022-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-17
    相关资源
    最近更新 更多