Neo4j 中的多线程:如果我想使用多线程,使用硬编码 id 或 where 条件是否更有效?

问题描述 投票:0回答:1

我目前正在从事 Spring Data Neo4j 项目。我的问题是我必须检查特定属性中具有特定值的节点是否已存在。如果是这种情况,那么我将使用该节点进行交易,否则我会生成一个新节点并使用新生成的节点。我想知道什么会更有效:我应该将属性设置为节点的 id,因为它是决定因素,是否创建新节点,或者我应该首先检查该节点是否存在带有 where 条件.

我认为 id 方式会更有效。但是,我必须保存大量节点,并且我想使用多线程。我非常确定 id 方法会存在竞争条件。但我也认为如果我先检查 where 条件,就会出现竞争条件。不过,我不太确定。 所以我的另一个问题是,如何实现多线程并保证我的交易不会发生竞争情况,我首先检查节点是否存在。

neo4j cypher spring-data-neo4j
1个回答
0
投票

我必须检查特定属性中具有特定值的节点是否已存在。如果是这种情况,那么我将使用该节点进行交易,否则我会生成一个新节点并使用新生成的节点。

这里有一个示例场景来解释如何执行此操作 - 让我们这样说:

  • 你有食物节点,还有人节点
  • 您想记录某个特定的人喜欢特定的食物
  • 如果该食物不存在,请继续创建它

这是一个查询,它将:

  • 查找任何匹配的 Person 节点
    name:'Alice'
  • 如果没有找到匹配的节点,则查询停止
  • MERGE
    行将:
    1. 查找并使用与
      name:'pear'
    2. 匹配的任何现有食物节点
    3. 创建一个新的食物节点
  • 如果它创建一个新的 Food 节点,那么它会将“name”设置为“pear”,并将颜色设置为“green”。
  • 最后,它将添加从 Person 节点到 Food 节点的
    :LIKES
    关系
MATCH (p:Person {name:'Alice'})
MERGE (f:Food {name:'pear'})
ON CREATE SET f.color = 'green'
CREATE (p) -[:LIKES]-> (f)

其他一些注意事项:

  • 如果多次运行此查询,每次都会创建一个新的
    :LIKES
    关系
  • 如果您想创建不超过一个这样的关系,请使用
    MERGE
    而不是
    CREATE
  • 在当前形式中 - 如果没有 Person.name 或 Food.name 的唯一性约束 - 最终可能会出现一个或多个 Person 节点指向一个或多个 Food 节点。

如果您想确保永远不会有多个 Food 节点匹配

name:'pear'
,您可以添加一个约束来保证“name”属性对于所有 Food 节点都是唯一的。

以下示例展示了如何做到这一点:

CREATE CONSTRAINT Food_name_unique IF NOT EXISTS
FOR (f:Food)
REQUIRE f.name IS UNIQUE

有了约束,您可以相信您的图表最终不会出现多个“梨”食物节点。在您的客户端代码中,您描述了运行多个线程 - 因此,调整您的代码以处理任何竞争条件(其中一个线程看到“没有梨”,尝试通过

MERGE
添加一个,但由于失去与另一个线程的竞争而失败)然后重试失败的查询。

© www.soinside.com 2019 - 2024. All rights reserved.