循环在neo4j中创建或更新节点

发布于 2025-02-12 18:46:32 字数 1750 浏览 1 评论 0 原文

我是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);
  }
};

我有技能串行的 开放交易;要么从交易中运行,要么使用其他会话。

有什么想法我该如何解决?

I am new to Neo4j so I quite stuck with looping through some values.

I have a list of skill to skill strings

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

And I want to create or update the relation between left side with right side

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);
  }
};

But every time when I run this I get the following 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.

Any idea how can I solve this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

冷血 2025-02-19 18:46:32
for (let item of data) {
    CreateSkillToSkillRelation(item);
}

不在等待您创造的承诺,因此您基本上试图与仅支持单个并发事务的单个会话同时运行所有这些承诺。

您应该在> CreateSkilltoskillRyation 的每个呼叫中​​创建一个会话,或使用单个会话等待每个呼叫。

尽管请注意,您可以在> CreateSkilltoSkillRyation 的末尾关闭会话,但仅在成功时,我建议您将等待session.close.close(); 移动到最后一个块中。

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

Is not awaiting the promises you create and so you are basically trying to run all of these promises concurrently against a single session which only supports a single concurrent transaction.

You should create a session in each call of CreateSkillToSkillRelation or await each call to it using a single session.

Though note you close the session at the end of CreateSkillToSkillRelation but only on success, might I suggest moving await session.close(); into a finally block.

戏舞 2025-02-19 18:46:32
  1. 同事的答案 @just_another_dotnet_devev 是绝对正确的:您可以在循环中运行异步功能在其中一个。

  2. 密码语言非常丰富,您可以使用它来完成尝试使用JavaScript循环进行的所有操作。像这样的东西,使用 merge < /a>:



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()
  }
};
  1. The answer of the colleague @just_another_dotnet_dev is absolutely correct: you run asynchronous functions in a loop, and close the session in one of them.

  2. The Cipher language is very rich, and you can use it to do everything that you tried to do with a loop in Javascript. Something like this, using UNWIND and MERGE:


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()
  }
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文