如何使用 Neo4jTemplate 合并而不是创建
How To Merge Instead of Create With Neo4jTemplate
我目前正在迭代一个数组,其中每个索引包含两个节点和一个关系 (Part_1 -> Part_2),并且我正在使用 Neo4jTemplate.save()方法将其持久化到数据库中。但是,一些索引具有重复的节点,这些节点将与其他节点有关系 (Part_2 -> Part_3)。我的版本目前每次都创建一个新的节点和关系,而不是在节点已经存在的情况下合并。
我读了这个 post,但我不明白如何实现它,以便两个相同的节点具有相同的 ID。我当前的代码是这样工作的:
- 创建两个节点
- 建立他们的关系
- 添加关系到节点
- 坚持使用 Neo4jTemplate.save()
我需要将什么更改为 MERGE 而不是 CREATE?我是否需要在坚持之前进行检查,或者是否有办法在坚持 SDN 4 时进行检查?
编辑:
我决定使用 Neo4jTemplate.query() 方法来编写 Cyper 查询,但是我不知道如何正确创建用于合并多个节点的参数。我可以像这样为一个节点正确创建 MERGE 语句:
Map<String, Object> params = new HashMap<String, Object>();
Map<String, Object> node = new HashMap<String, Object>();
node.put("name", "Part_1");
params.put("props", node_1);
String query = "MERGE( n1:Part {name:{props}.name} )";
template.query(query, params);
我的目标是在两个节点上调用合并,然后再次调用合并以在一个语句中创建关系。我的代码现在看起来像这样:
Map<String, Object> params = new HashMap<String, Object>();
List<Map<String, Object>> maps;
Map<String, Object> node1 = new HashMap<String, Object>();
Map<String, Object> node2 = new HashMap<String, Object>();
node1.put("name1", "Part_1");
node2.put("name2", "Part_2");
maps = Arrays.asList(node_1, node_2)
params.put("props", maps);
String query = "MERGE( n1:Part {name:{props}.name1} )
MERGE( n2:Part {name:{props}.name2 )
MERGE(n1)-[:CREATED]->(n2)";
template.query(query, params);
到目前为止,我所看到的所有 examples 参数中的多个节点只是在调用时遍历整个事物。我还没有找到任何具有参数的示例,您可以在其中指定您所指的特定节点。如何在我引用某个节点的地方创建一个参数?提前致谢!
如果不查看您的代码就很难提出要更改的内容,但听起来就像您每次都在保存新的实体实例一样。
传递给 Neo4jTemplate.save(entity)
的实体在写入数据库后应使用 ID 进行更新。 SDN 将尝试更新已经具有 ID 的节点,因此我建议重新使用实体实例而不是创建新实例。
如果您不想自己管理这些实体,您可以尝试在步骤 1 中加载实体,然后仅在它们尚不存在时才创建它们。
我目前正在迭代一个数组,其中每个索引包含两个节点和一个关系 (Part_1 -> Part_2),并且我正在使用 Neo4jTemplate.save()方法将其持久化到数据库中。但是,一些索引具有重复的节点,这些节点将与其他节点有关系 (Part_2 -> Part_3)。我的版本目前每次都创建一个新的节点和关系,而不是在节点已经存在的情况下合并。
我读了这个 post,但我不明白如何实现它,以便两个相同的节点具有相同的 ID。我当前的代码是这样工作的:
- 创建两个节点
- 建立他们的关系
- 添加关系到节点
- 坚持使用 Neo4jTemplate.save()
我需要将什么更改为 MERGE 而不是 CREATE?我是否需要在坚持之前进行检查,或者是否有办法在坚持 SDN 4 时进行检查?
编辑:
我决定使用 Neo4jTemplate.query() 方法来编写 Cyper 查询,但是我不知道如何正确创建用于合并多个节点的参数。我可以像这样为一个节点正确创建 MERGE 语句:
Map<String, Object> params = new HashMap<String, Object>();
Map<String, Object> node = new HashMap<String, Object>();node.put("name", "Part_1");
params.put("props", node_1);
String query = "MERGE( n1:Part {name:{props}.name} )";template.query(query, params);
我的目标是在两个节点上调用合并,然后再次调用合并以在一个语句中创建关系。我的代码现在看起来像这样:
Map<String, Object> params = new HashMap<String, Object>();
List<Map<String, Object>> maps;
Map<String, Object> node1 = new HashMap<String, Object>();
Map<String, Object> node2 = new HashMap<String, Object>();node1.put("name1", "Part_1");
node2.put("name2", "Part_2");
maps = Arrays.asList(node_1, node_2)params.put("props", maps);
String query = "MERGE( n1:Part {name:{props}.name1} )
MERGE( n2:Part {name:{props}.name2 )
MERGE(n1)-[:CREATED]->(n2)";template.query(query, params);
到目前为止,我所看到的所有 examples 参数中的多个节点只是在调用时遍历整个事物。我还没有找到任何具有参数的示例,您可以在其中指定您所指的特定节点。如何在我引用某个节点的地方创建一个参数?提前致谢!
如果不查看您的代码就很难提出要更改的内容,但听起来就像您每次都在保存新的实体实例一样。
传递给 Neo4jTemplate.save(entity)
的实体在写入数据库后应使用 ID 进行更新。 SDN 将尝试更新已经具有 ID 的节点,因此我建议重新使用实体实例而不是创建新实例。
如果您不想自己管理这些实体,您可以尝试在步骤 1 中加载实体,然后仅在它们尚不存在时才创建它们。