|
@@ -10,6 +10,7 @@ import org.neo4j.driver.v1.Session;
|
|
|
import org.neo4j.driver.v1.StatementResult;
|
|
|
import org.neo4j.driver.v1.Values;
|
|
|
import org.neo4j.driver.v1.types.Node;
|
|
|
+import org.neo4j.driver.v1.types.Relationship;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Repository;
|
|
|
|
|
@@ -190,36 +191,67 @@ public class BaseNodeRepository {
|
|
|
*/
|
|
|
public Map<String, Object> mergeNode(MergeNodeParam mergeNodeParam) {
|
|
|
|
|
|
- String query = String.format("MATCH (a:`%s`), (b:`%s`)\n" +
|
|
|
- "WHERE id(a) = $firstId AND id(b) = $secondId\n" +
|
|
|
- "// 创建一个新的节点 MergedNode 并合并属性\n" +
|
|
|
- "MERGE (m:`%s` {name: $newName})\n" +
|
|
|
- "// 合并节点 A 和节点 B 的所有关系到新的节点\n" +
|
|
|
- "// 从 A 到其他节点的关系\n" +
|
|
|
- "WITH a, b, m\n" +
|
|
|
- "MATCH (a)-[rA]->(target)\n" +
|
|
|
- "MERGE (m)-[rAMerged]->(target)\n" +
|
|
|
- "SET rAMerged = rA\n" +
|
|
|
- "\n" +
|
|
|
- "// 从 B 到其他节点的关系\n" +
|
|
|
- "MATCH (b)-[rB]->(target2)\n" +
|
|
|
- "MERGE (m)-[rBMerged]->(target2)\n" +
|
|
|
- "SET rBMerged = rB\n" +
|
|
|
- "\n" +
|
|
|
- "// 删除原有的两个节点\n" +
|
|
|
- "WITH m, a, b\n" +
|
|
|
- "DETACH DELETE a, b\n" +
|
|
|
- "RETURN m\n", mergeNodeParam.getFirstLabel(), mergeNodeParam.getSecondLabel(), mergeNodeParam.getNewLabel());
|
|
|
-
|
|
|
try(Session session = neo4jUtil.getSession()) {
|
|
|
- StatementResult result = session.run(query,Values.parameters("firstId", mergeNodeParam.getFirstId(),"secondId", mergeNodeParam.getSecondId(),"newName", mergeNodeParam.getNewName()));
|
|
|
- Map<String,Object> map = new HashMap<>();
|
|
|
- if(result.hasNext()) {
|
|
|
- Node node = result.single().get("m").asNode();
|
|
|
- map.put("id", node.id());
|
|
|
- map.put("labels", node.labels());
|
|
|
- map.put("properties", node.asMap());
|
|
|
+ // 找到要合并的两个节点
|
|
|
+ String firstQuery = String.format("MATCH (a:`%s`) WHERE id(a) = $firstId RETURN a", mergeNodeParam.getFirstLabel());
|
|
|
+ String secondQuery = String.format("MATCH (b:`%s`) WHERE id(b) = $secondId RETURN b", mergeNodeParam.getSecondLabel());
|
|
|
+ StatementResult aResult = session.run(firstQuery,Values.parameters("firstId", mergeNodeParam.getFirstId()));
|
|
|
+ Record aRecord = aResult.single();
|
|
|
+ Node a = aRecord.get("a").asNode();
|
|
|
+ StatementResult bResult = session.run(secondQuery,Values.parameters("secondId", mergeNodeParam.getSecondId()));
|
|
|
+ Record bRecord = bResult.single();
|
|
|
+ Node b = bRecord.get("b").asNode();
|
|
|
+
|
|
|
+ // 创建新节点
|
|
|
+ Map<String, Object> newNodeProps = new HashMap<>();
|
|
|
+ newNodeProps.put("name", mergeNodeParam.getNewName());
|
|
|
+ // 合并属性
|
|
|
+ for (String key : a.keys()) {
|
|
|
+ newNodeProps.put(key, a.get(key).asObject());
|
|
|
+ }
|
|
|
+ for (String key : b.keys()) {
|
|
|
+ if (!newNodeProps.containsKey(key)) {
|
|
|
+ newNodeProps.put(key, b.get(key).asObject());
|
|
|
+ }
|
|
|
}
|
|
|
+ StatementResult newNodeResult = session.run(String.format("MERGE (n:`%s` $props) RETURN n", mergeNodeParam.getNewLabel()), Values.parameters("props", newNodeProps));
|
|
|
+ Node newNode = newNodeResult.single().get("n").asNode();
|
|
|
+ long newNodeId = newNode.id();
|
|
|
+
|
|
|
+ // 合并关系
|
|
|
+ String firstRelationQuery = String.format("MATCH (a:`%s`)-[aR]-(aOther) WHERE id(a) = $firstId RETURN a,aR,aOther", mergeNodeParam.getFirstLabel());
|
|
|
+ String secondRelationQuery = String.format("MATCH (b:`%s`)-[bR]-(bOther) WHERE id(b) = $secondId RETURN b,bR,bOther", mergeNodeParam.getSecondLabel());
|
|
|
+ StatementResult aRelationResult = session.run(firstRelationQuery,Values.parameters("firstId", mergeNodeParam.getFirstId()));
|
|
|
+ StatementResult bRelationResult = session.run(secondRelationQuery,Values.parameters("secondId", mergeNodeParam.getSecondId()));
|
|
|
+ while (aRelationResult.hasNext()) {
|
|
|
+ Record record = aRelationResult.next();
|
|
|
+ Relationship relationship = record.get("aR").asRelationship();
|
|
|
+ String relType = relationship.type();
|
|
|
+ Node aOtherNode = record.get("aOther").asNode();
|
|
|
+ session.run("MATCH (a), (other) WHERE id(a) = $newNodeId and id(other) = $otherId " +
|
|
|
+ "MERGE (a)-[newRel:$relType]->(other) SET newRel = $relProps",
|
|
|
+ Values.parameters("newNodeId", newNodeId,"otherId", aOtherNode.id(), "relType", relType, "relProps", relationship.asMap()));
|
|
|
+
|
|
|
+ }
|
|
|
+ while (bRelationResult.hasNext()) {
|
|
|
+ Record record = aRelationResult.next();
|
|
|
+ Relationship relationship = record.get("bR").asRelationship();
|
|
|
+ String relType = relationship.type();
|
|
|
+ Node bOtherNode = record.get("bOther").asNode();
|
|
|
+ session.run("MATCH (a), (other) WHERE id(a) = $newNodeId and id(other) = $otherId " +
|
|
|
+ "MERGE (a)-[newRel:$relType]->(other) SET newRel = $relProps",
|
|
|
+ Values.parameters("newNodeId", newNodeId,"otherId", bOtherNode.id(), "relType", relType, "relProps", relationship.asMap()));
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ // 删除原始节点
|
|
|
+ session.run(String.format("MATCH (a:`%s`) WHERE id(a) = $firstId DETACH DELETE a", mergeNodeParam.getFirstLabel()),Values.parameters("firstId", mergeNodeParam.getFirstId()));
|
|
|
+ session.run(String.format("MATCH (a:`%s`) WHERE id(a) = $secondId DETACH DELETE a", mergeNodeParam.getSecondLabel()),Values.parameters("secondId", mergeNodeParam.getSecondId()));
|
|
|
+
|
|
|
+ Map<String,Object> map = new HashMap<>();
|
|
|
+ map.put("id", newNode.id());
|
|
|
+ map.put("labels", newNode.labels());
|
|
|
+ map.put("properties", newNode.asMap());
|
|
|
return map;
|
|
|
}
|
|
|
}
|