循环以在Neo4j中创建或更新节点

envsm3lx  于 2022-11-05  发布在  其他
关注(0)|答案(2)|浏览(306)

我是Neo4j的新手,所以我一直在循环一些值。
我有一个技能到技能字符串列表

let data = [
  'big_data, business_intelligence',
  'big_data, data_collection',
  'big_data, economic_growth',
  'big_data, economy'
]

我想创建或更新左侧与右侧之间的关系

for (let item of data) {
    CreateSkillToSkillRelation(item);
}

const CreateSkillToSkillRelation = async (relation) => {
  let mainSkill = relation.split(",")[0];
  let secundarySkill = relation.split(",")[1];

  try {
    // Check if the relationship exists
    let { records } = await session.run(
      "MATCH(main:SKILL {name:$mainSkill}) -[relation:SKILL_TO_SKILL]-> (secundary:SKILL {name:$secundarySkill}) RETURN relation",
      { mainSkill, secundarySkill }
    );

    let count =
      records[0]?._fields[0].properties.count > 0
        ? records[0]._fields[0].properties.count + 1
        : 1;

    // If count is greater then 1 then lets update the counter
    if (count > 1) {
      await session.run(
        "MATCH(main:SKILL {name:$mainSkill}) -[relation:SKILL_TO_SKILL]-> (secundary:SKILL {name:$secundarySkill}) SET relation.count = $count RETURN main, secundary",
        {
          mainSkill,
          secundarySkill,
          count,
        }
      );
    }
    // Otherwise the skill relation is not created so lets create one
    else {
      await session.run(
        "CREATE(main:SKILL {name:$mainSkill}) -[:SKILL_TO_SKILL {count:$count}]-> (secundary:SKILL {name:$secundarySkill}) RETURN main, secundary",
        {
          mainSkill,
          secundarySkill,
          count,
        }
      );
    }

    await session.close();
  } catch (error) {
    console.log(error);
  }
};

但每次运行时,我都会得到以下错误Neo4jError: Queries cannot be run directly on a session with an open transaction; either run from within the transaction or use a different session.
你知道我该怎么解决吗?

83qze16e

83qze16e1#

for (let item of data) {
    CreateSkillToSkillRelation(item);
}

不等待您创建的承诺,因此您基本上是在尝试针对仅支持单个并发事务的单个会话并发运行所有这些承诺。
您应该在CreateSkillToSkillRelation的每个调用中创建一个会话,或者使用单个会话等待对它的每个调用。
虽然注意到您在CreateSkillToSkillRelation结束时关闭会话,但仅在成功时关闭,我建议将await session.close();移到finally块中。

c9x0cxw0

c9x0cxw02#

1.同事@just_another_dotnet_dev的回答绝对正确:在循环中运行异步函数,并在其中一个函数中关闭会话。

  1. Cipher语言非常丰富,你可以用它来做你在Javascript中用循环所做的一切。
const CreateSkillToSkillRelations = async (data) => {
  const session = driver.session();
  try {
    let { records } = await session.run(
        `WITH split(row, ',') as rels
         WITH trim(rels[0]) as mainSkill, 
              trim(rels[1]) as secundarySkill
         MERGE (main:SKILL {name: mainSkill})
               -[relation:SKILL_TO_SKILL]->
               (secundary:SKILL {name: secundarySkill})
           ON CREATE SET relation.count = 1
           ON MATCH SET relation.count = relation.count + 1
         RETURN main, relation, secundary`,
         { data }
    );
  } catch (error) {
    console.log(error);
  } finally {
    await session.close()
  }
};

相关问题