为什么Node.js中的'MERGE'语句仍然会在Neo4j中创建重复的节点?

x33g5p2x  于 2023-05-17  发布在  Node.js
关注(0)|答案(1)|浏览(248)

我目前正在做一个Node.js项目,该项目涉及使用'MERGE'语句在Neo4j中创建节点。然而,我注意到,即使我使用“MERGE”来确保不创建重复节点,该语句有时仍然会创建重复节点。
我已经检查了Neo4j文档,并在网上搜索了类似的问题,但我还没有找到解决这个问题的方法。谁能帮助我理解为什么会发生这种情况,以及我如何防止它在未来发生?我在here上提供了代码存储库。
任何建议或见解将不胜感激。谢谢你!
下面是我使用的代码:

const neo4j = require('neo4j-driver')

const url = `neo4j://test-neo4j:7687`;

(async ()=>{
    console.log(`start connect to neo4j : ${url}`);
    const driver = neo4j.driver(
        url,
        neo4j.auth.basic('neo4j', 'nodejs_to_neo4j')
    )

    const endFn = (session)=>{
        setTimeout(()=>{
            session.close();
            driver.close();

            console.log(`end connect to neo4j : ${url}`);
        }, 3000);
    };

    setTimeout(async ()=>{

        for(let i= 0; i < 10 ; i++){
            const session = driver.session();
            let userId = '123';
            let nameParam = 'John Doe';

            const query = 'MERGE (n:Person {user_id: $userId,  name: $nameParam}) RETURN n';
            console.log(
                `query(${i + 1}): ${query}`
                .replace('$userId', userId)
                .replace('$nameParam', nameParam)
            );

            let dictResult = session.run(query, { userId, nameParam });

            if(i === 9) {
                dictResult.then(endFn(session));
            } else {
                dictResult.then();
            }
        }
    }, 1000);

})();

我希望这段代码只在数据库中不存在具有相同属性的节点时创建一个新节点。但是,在某些情况下,即使已经存在同名节点,代码也会创建新节点。

h7appiyu

h7appiyu1#

重要的是要理解,除非存在唯一性约束,否则单个节点模式上的MERGE可能会创建重复项。
因此,您需要确保:Person(user_id)具有唯一性约束:

CREATE CONSTRAINT Person_user_id FOR (p:Person) REQUIRE p.user_id IS UNIQUE;

您还应该更改查询,以便仅对受约束的属性user_id使用MERGE

MERGE (n:Person {user_id: $userId}) ON CREATE SET n.name = $nameParam RETURN n

最后,您需要关闭每个session,而不仅仅是最后一个。如果不关闭会话,则会泄漏资源。推荐的方法是使用try上下文块来确保每个会话始终关闭。

相关问题