yuchengwei hai 7 meses
pai
achega
e592d09dd4

+ 30 - 18
src/main/java/com/qizhen/healsphere/config/Neo4jUtil.java

@@ -4,35 +4,47 @@ import org.neo4j.driver.v1.AuthTokens;
 import org.neo4j.driver.v1.Driver;
 import org.neo4j.driver.v1.GraphDatabase;
 import org.neo4j.driver.v1.Session;
-import org.springframework.context.annotation.Configuration;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.stereotype.Component;
 
-@Configuration
+@Component
 public class Neo4jUtil {
 
-//    @Value("${spring.neo4j.uri}")
-    //private static String url = "bolt://173.18.12.194:7687";
-    private static String url = "bolt://172.16.8.59:7687";
-//    @Value("${spring.neo4j.authentication.username}")
-    private static String username = "neo4j";
+    @Value("${spring.neo4j.uri}")
+    private String url;
 
-//    @Value("${spring.neo4j.authentication.password}")
-//    private static String password = "12345678";
-    private static String password = "1Qaz@wsx";
+    @Value("${spring.neo4j.authentication.username}")
+    private String username;
 
-    private static Driver driver;
+    @Value("${spring.neo4j.authentication.password}")
+    private String password;
 
-    static {
+    private Driver driver;
+
+    @Bean
+    public Driver neo4jDriver() {
         driver = GraphDatabase.driver(url, AuthTokens.basic(username, password));
+        return driver;
     }
 
-
-    public static Session getSession() {
+    public Session getSession() {
         return driver.session();
     }
 
-    public static void closeDriver() {
-        if (driver!= null) {
-            driver.close();
+    @Component
+    public static class Neo4jDriverShutdown {
+        private final Driver driver;
+
+        public Neo4jDriverShutdown(Driver driver) {
+            this.driver = driver;
+        }
+
+        // 在容器关闭时关闭 Driver
+        public void shutdown() {
+            if (driver!= null) {
+                driver.close();
+            }
         }
     }
-}
+}

+ 3 - 3
src/main/java/com/qizhen/healsphere/facade/KgFacade.java

@@ -63,7 +63,7 @@ public class KgFacade extends KgServiceImpl {
 
             GraphDTO graphDTO = res.get(0);
             GNodeDTO gNodeDTO
-                    = new GNodeDTO(graphDTO.getLabel(), 0, graphDTO.getName(), nodeId, "circle", 50,graphDTO.getProperties());
+                    = new GNodeDTO(graphDTO.getLabel(), 0, graphDTO.getName(), nodeId, "circle", 50,graphDTO.getProperties(),graphDTO.getId());
             nodeId++;
             node.add(gNodeDTO);
             if (CollUtil.isNotEmpty(graphDTO.getENodeRSDTOS())) {
@@ -75,7 +75,7 @@ public class KgFacade extends KgServiceImpl {
                         rsId++;
                     }
                     GNodeDTO nNodeDTO
-                            = new GNodeDTO("", 1, "", nodeId, "diamond", 10,graphDTO.getProperties());
+                            = new GNodeDTO("", 1, "", nodeId, "diamond", 10,graphDTO.getProperties(),nodeId);
                     node.add(nNodeDTO);
                     links.add(new LinkDTO(gNodeDTO.getName(), nNodeDTO.getName(), baseNodeRSDTO.getRType()));
                     nodeId++;
@@ -87,7 +87,7 @@ public class KgFacade extends KgServiceImpl {
                             }
                             GNodeDTO eNodeDTO
                                     = new GNodeDTO(baseNodeDTO.getLabel(), cMap.get(baseNodeRSDTO.getRType()),
-                                    baseNodeDTO.getName(), nodeId, symbol, 28, baseNodeDTO.getProperties());
+                                    baseNodeDTO.getName(), nodeId, symbol, 28, baseNodeDTO.getProperties(),baseNodeDTO.getId());
                             nodeId++;
                             node.add(eNodeDTO);
                             links.add(new LinkDTO(nNodeDTO.getName(), eNodeDTO.getName(), ""));

+ 56 - 14
src/main/java/com/qizhen/healsphere/repository/neo4j/BaseNodeRepository.java

@@ -1,5 +1,6 @@
 package com.qizhen.healsphere.repository.neo4j;
 
+import cn.hutool.core.collection.CollUtil;
 import com.qizhen.healsphere.config.Neo4jUtil;
 import org.neo4j.driver.v1.*;
 import com.qizhen.healsphere.repository.neo4j.entity.BaseEntity;
@@ -8,6 +9,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.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Repository;
 
 import java.util.ArrayList;
@@ -19,6 +21,9 @@ import java.util.stream.Collectors;
 @Repository
 public class BaseNodeRepository {
 
+    @Autowired
+    private Neo4jUtil neo4jUtil;
+
     /**
      * 根据名字和标签查询实体属性
      * @param label
@@ -26,8 +31,8 @@ public class BaseNodeRepository {
      * @return 实体map
      */
     public Map<String,Object> findNodeByName(String label,String name) {
-        String query = String.format("MATCH (n:`%s`) WHERE n.name = $name and n.is_deleted = 'N' RETURN n", label);
-        try(Session session = Neo4jUtil.getSession()) {
+        String query = String.format("MATCH (n:`%s`) WHERE n.name = $name and (n.is_deleted = 'N' or NOT exists(n.is_deleted)) RETURN n", label);
+        try(Session session = neo4jUtil.getSession()) {
             StatementResult result = session.run(query,Values.parameters("name", name));
             Map<String,Object> map = new HashMap<>();
             if(result.hasNext()) {
@@ -43,8 +48,8 @@ public class BaseNodeRepository {
     }
 
     public List<String> findNodeByNameLike(String label,String name) {
-        String query = String.format("MATCH (n:`%s`) WHERE n.name contains $name and n.is_deleted = 'N' return distinct n.name limit 20", label);
-        try(Session session = Neo4jUtil.getSession()) {
+        String query = String.format("MATCH (n:`%s`) WHERE n.name contains $name and (n.is_deleted = 'N' or NOT exists(n.is_deleted)) return distinct n.name limit 20", label);
+        try(Session session = neo4jUtil.getSession()) {
             StatementResult result = session.run(query,Values.parameters("name", name));
             List<String> names = new ArrayList<>();
             if(result.hasNext()) {
@@ -64,8 +69,8 @@ public class BaseNodeRepository {
      * @return 实体map
      */
     public Map<String,Object> findNodeById(Long id) {
-        String query = "MATCH (n) WHERE id(n) = $nodeId and n.is_deleted = 'N' RETURN n";
-        try(Session session = Neo4jUtil.getSession()) {
+        String query = "MATCH (n) WHERE id(n) = $nodeId and (n.is_deleted = 'N' or NOT exists(n.is_deleted)) RETURN n";
+        try(Session session = neo4jUtil.getSession()) {
             StatementResult result = session.run(query,Values.parameters("nodeId", id));
             Map<String,Object> map = new HashMap<>();
             if(result.hasNext()) {
@@ -87,9 +92,9 @@ public class BaseNodeRepository {
      * @return 实体map列表
      */
     public List<Map<String,Object>> findNodeListByName(String label, String name) {
-        String query = String.format("MATCH (n:`%s`) WHERE n.name contains $name and n.is_deleted = 'N' RETURN n", label);
+        String query = String.format("MATCH (n:`%s`) WHERE n.name contains $name and (n.is_deleted = 'N' or NOT exists(n.is_deleted)) RETURN n", label);
 
-        try(Session session = Neo4jUtil.getSession()) {
+        try(Session session = neo4jUtil.getSession()) {
             StatementResult result = session.run(query,Values.parameters("name", name));
             List<Map<String,Object>> listMap = new ArrayList<>();
             if(result.hasNext()) {
@@ -116,6 +121,9 @@ public class BaseNodeRepository {
      */
     public Map<String, Object> createNode(String label, Map<String, Object> properties) {
         StringBuilder createClause = new StringBuilder();
+        if (CollUtil.isEmpty(properties)) {
+            properties = new HashMap<>();
+        }
         properties.put("is_deleted","N");
         properties.forEach((key, value) -> createClause.append(key).append(": '").append(value).append("'").append(", "));
 
@@ -126,7 +134,7 @@ public class BaseNodeRepository {
 
         String query = String.format("MERGE (n:`%s` { %s }) RETURN n", label, createClause);
 
-        try(Session session = Neo4jUtil.getSession()) {
+        try(Session session = neo4jUtil.getSession()) {
             StatementResult result = session.run(query);
             Map<String,Object> map = new HashMap<>();
             if(result.hasNext()) {
@@ -147,7 +155,7 @@ public class BaseNodeRepository {
      */
     public Map<String, Object> updateNode(Long nodeId, String name) {
         String query = "MATCH (n) WHERE id(n) = $nodeId SET n.name=$name RETURN n";
-        try(Session session = Neo4jUtil.getSession()) {
+        try(Session session = neo4jUtil.getSession()) {
             StatementResult result = session.run(query,Values.parameters("nodeId", nodeId,"name", name));
             Map<String,Object> map = new HashMap<>();
             if(result.hasNext()) {
@@ -168,11 +176,45 @@ public class BaseNodeRepository {
         String query = "MATCH (n) WHERE id(n) = $nodeId SET n.is_deleted = 'Y' " +
                 "WITH n MATCH (n)-[r]-() " +
                 "DELETE r";
-        try(Session session = Neo4jUtil.getSession()) {
+        try(Session session = neo4jUtil.getSession()) {
             session.run(query,Values.parameters("nodeId", nodeId));
         }
     }
 
+    /**
+     * 实体合并
+     * @param label
+     * @param properties
+     * @return 实体map
+     */
+    public Map<String, Object> mergeNode(String label, Map<String, Object> properties) {
+        StringBuilder createClause = new StringBuilder();
+        if (CollUtil.isEmpty(properties)) {
+            properties = new HashMap<>();
+        }
+        properties.put("is_deleted","N");
+        properties.forEach((key, value) -> createClause.append(key).append(": '").append(value).append("'").append(", "));
+
+        // 移除最后的逗号
+        if (createClause.length() > 0) {
+            createClause.setLength(createClause.length() - 2);
+        }
+
+        String query = String.format("MERGE (n:`%s` { %s }) RETURN n", label, createClause);
+
+        try(Session session = neo4jUtil.getSession()) {
+            StatementResult result = session.run(query);
+            Map<String,Object> map = new HashMap<>();
+            if(result.hasNext()) {
+                Node node = result.single().get("n").asNode();
+                map.put("id", node.id());
+                map.put("labels", node.labels());
+                map.put("properties", node.asMap());
+            }
+            return map;
+        }
+    }
+
     /**
      * 新增实体
      * @param label
@@ -191,7 +233,7 @@ public class BaseNodeRepository {
 
         String query = String.format("MERGE (n:`%s` { %s }) RETURN n", label, createClause);
 
-        try(Session session = Neo4jUtil.getSession()) {
+        try(Session session = neo4jUtil.getSession()) {
             StatementResult result = session.run(query);
 
             if(result.hasNext()) {
@@ -208,8 +250,8 @@ public class BaseNodeRepository {
      * @return 实体map
      */
     public BaseEntity byName(String label,String name) {
-        String query = String.format("MATCH (n:`%s`) WHERE n.name = $name and n.is_deleted = 'N' RETURN n", label);
-        try(Session session = Neo4jUtil.getSession()) {
+        String query = String.format("MATCH (n:`%s`) WHERE n.name = $name and (n.is_deleted = 'N' or NOT exists(n.is_deleted)) RETURN n", label);
+        try(Session session = neo4jUtil.getSession()) {
             StatementResult result = session.run(query,Values.parameters("name", name));
             if(result.hasNext()) {
                 return buildBaseEntity(result);

+ 6 - 3
src/main/java/com/qizhen/healsphere/repository/neo4j/BasePropertyRepository.java

@@ -5,6 +5,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.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Repository;
 
 import java.util.HashMap;
@@ -13,6 +14,8 @@ import java.util.Map;
 @Repository
 public class BasePropertyRepository {
 
+    @Autowired
+    private Neo4jUtil neo4jUtil;
 
     /**
      * 新增实体属性
@@ -32,7 +35,7 @@ public class BasePropertyRepository {
 
         String query = String.format("MATCH (n:`%s`) WHERE id(n) = $nodeId SET %s RETURN n", label, setClause);
 
-        try(Session session = Neo4jUtil.getSession()) {
+        try(Session session = neo4jUtil.getSession()) {
             StatementResult result = session.run(query, Values.parameters("nodeId", nodeId));
             Map<String,Object> map = new HashMap<>();
             if(result.hasNext()) {
@@ -56,7 +59,7 @@ public class BasePropertyRepository {
     public Map<String,Object> deleteProperty(String label, Long nodeId,String propertyName) {
         String query = String.format("MATCH (n:`%s`) WHERE id(n) = $nodeId REMOVE n.%s RETURN n", label,propertyName);
 
-        try(Session session = Neo4jUtil.getSession()) {
+        try(Session session = neo4jUtil.getSession()) {
             StatementResult result = session.run(query,Values.parameters("nodeId", nodeId));
             Map<String,Object> map = new HashMap<>();
             if(result.hasNext()) {
@@ -82,7 +85,7 @@ public class BasePropertyRepository {
         String query = String.format("MATCH (n:`%s`) WHERE id(n) = $nodeId REMOVE n.%s " +
                 "SET n.%s = $newPropertyValue RETURN n", label,oldPropertyName,newPropertyName);
 
-        try(Session session = Neo4jUtil.getSession()) {
+        try(Session session = neo4jUtil.getSession()) {
             StatementResult result = session.run(query,Values.parameters("nodeId", nodeId,"newPropertyValue", newPropertyValue));
             Map<String,Object> map = new HashMap<>();
             if(result.hasNext()) {

+ 50 - 14
src/main/java/com/qizhen/healsphere/repository/neo4j/BaseRelationshipRepository.java

@@ -1,7 +1,9 @@
 package com.qizhen.healsphere.repository.neo4j;
 
+import cn.hutool.core.collection.CollUtil;
 import com.qizhen.healsphere.config.Neo4jUtil;
 import org.neo4j.driver.v1.*;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Repository;
 
 import java.util.*;
@@ -10,6 +12,9 @@ import java.util.stream.Collectors;
 @Repository
 public class BaseRelationshipRepository {
 
+    @Autowired
+    private Neo4jUtil neo4jUtil;
+
     /**
      * 新增关系
      * @param startLabel
@@ -17,24 +22,55 @@ public class BaseRelationshipRepository {
      * @param endLabel
      * @param endId
      * @param relationshipType
-     * @param properties
      */
-    public void createRelationship(String startLabel, Long startId, String endLabel, Long endId, String relationshipType, Map<String, Object> properties) {
-//        StringBuilder setClause = new StringBuilder();
-//        properties.forEach((key, value) -> setClause.append("r.").append(key).append(" = '").append(value).append("'").append(", "));
-//
-//        if (setClause.length() > 0) {
-//            setClause.setLength(setClause.length() - 2);
-//        }
+    public Boolean isExistRelationship(String startLabel, Long startId, String endLabel, Long endId, String relationshipType) {
 
         String query = String.format(
-                "MATCH (a:`%s`), (b:`%s`) WHERE id(a) = $startId AND id(b) = $endId " +
-                        "MERGE (a)-[r:`%s`]->(b) " +
+                "MATCH (a:`%s`) -[r:`%s`]-(b:`%s`) WHERE id(a) = $startId AND id(b) = $endId " +
                         "RETURN r",
                 startLabel, endLabel, relationshipType
         );
 
-        try(Session session = Neo4jUtil.getSession()) {
+        try(Session session = neo4jUtil.getSession()) {
+            StatementResult result = session.run(query, Values.parameters("startId", startId, "endId", endId));
+            return result.hasNext();
+        }
+    }
+
+    /**
+     * 新增关系
+     * @param startLabel
+     * @param startId
+     * @param endLabel
+     * @param endId
+     * @param relationshipType
+     * @param properties
+     */
+    public void createRelationship(String startLabel, Long startId, String endLabel, Long endId, String relationshipType, Map<String, Object> properties) {
+        StringBuilder setClause = new StringBuilder();
+        if (CollUtil.isNotEmpty(properties)) {
+            properties.forEach((key, value) -> setClause.append("r.").append(key).append(" = '").append(value).append("'").append(", "));
+        }
+        String query;
+        if (setClause.length() > 0) {
+            setClause.setLength(setClause.length() - 2);
+            query = String.format(
+                    "MATCH (a:`%s`), (b:`%s`) WHERE id(a) = $startId AND id(b) = $endId " +
+                            "MERGE (a)-[r:`%s`]->(b) " +
+                            "SET %s RETURN r",
+                    startLabel, endLabel, relationshipType,setClause
+            );
+        }else {
+            query = String.format(
+                    "MATCH (a:`%s`), (b:`%s`) WHERE id(a) = $startId AND id(b) = $endId " +
+                            "MERGE (a)-[r:`%s`]->(b) " +
+                            "RETURN r",
+                    startLabel, endLabel, relationshipType
+            );
+        }
+
+
+        try(Session session = neo4jUtil.getSession()) {
             session.run(query, Values.parameters("startId", startId,"endId",endId));
         }
     }
@@ -54,7 +90,7 @@ public class BaseRelationshipRepository {
                 oldRelationshipType, newRelationshipType
         );
 
-        try(Session session = Neo4jUtil.getSession()) {
+        try(Session session = neo4jUtil.getSession()) {
             session.run(query);
         }
     }
@@ -68,7 +104,7 @@ public class BaseRelationshipRepository {
 
         String query = "match ()-[r]-() where type(r) contains $name return distinct type(r)";
 
-        try(Session session = Neo4jUtil.getSession()) {
+        try(Session session = neo4jUtil.getSession()) {
             StatementResult result = session.run(query, Values.parameters("name", name));
             List<String> list = new ArrayList<>();
             if(result.hasNext()) {
@@ -96,7 +132,7 @@ public class BaseRelationshipRepository {
                 startLabel, relationshipType, endLabel
         );
 
-        try(Session session = Neo4jUtil.getSession()) {
+        try(Session session = neo4jUtil.getSession()) {
             session.run(query, Values.parameters("startId", startId,"endId",endId));
         }
     }

+ 7 - 22
src/main/java/com/qizhen/healsphere/service/impl/KgServiceImpl.java

@@ -12,6 +12,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.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import java.util.ArrayList;
@@ -29,27 +30,22 @@ import java.util.Map;
  */
 @Service
 public class KgServiceImpl implements KgService {
-//    @Autowired
-//    private KgMapper kgMapper;
 
-//    @Autowired
-//    private Neo4jTemplate neo4jTemplate;
-//
-//    @Autowired
-//    Neo4jClient neo4jClient;
+    @Autowired
+    private Neo4jUtil neo4jUtil;
 
     @Override
     public List<GraphDTO> getGraph(KgQuery kgQuery){
         Map<String,Object> map = new HashMap<>();
         map.put("inputStr",kgQuery.getInputStr());
         String cypherQuery = "MATCH (n:" + kgQuery.getLabelName() + ")-[r]->(m)\n" +
-                "            where n.name = $inputStr\n" +
+                "            where n.name = $inputStr and (n.is_deleted = 'N' or NOT exists(n.is_deleted))\n" +
                 "            OPTIONAL MATCH p=(m)-[]->(o) where head(Labels(m)) in [\"疾病\",\"症状\",\"药品通用名\",\"手术和操作\",\"实验室检查\",\"辅助检查\"]\n" +
                 "            RETURN n,Type (r) as rType, m, count(p) as pCount\n" +
                 "            ORDER BY rType";
 
 
-        try(Session session = Neo4jUtil.getSession()) {
+        try(Session session = neo4jUtil.getSession()) {
             StatementResult result = session.run(cypherQuery, Values.parameters("inputStr", kgQuery.getInputStr()));
             List<GraphDTO> graphDTOList = new ArrayList<>();
 
@@ -111,33 +107,22 @@ public class KgServiceImpl implements KgService {
             return graphDTOList;
 
         }
-
-//        QueryFragmentsAndParameters parameters = new QueryFragmentsAndParameters(cypherQuery,map);
-
-
-//        return neo4jTemplate.toExecutableQuery(GraphDTO.class,parameters).getResults();
-//        return null;
     }
 
     @Override
     public List<Map<String,Object>> getGraphNew(KgQuery kgQuery){
         String cypherQuery = "MATCH (n:" + kgQuery.getLabelName() + ")-[r]->(m)\n" +
-                "            where n.name = $inputStr\n" +
+                "            where n.name = $inputStr and (n.is_deleted = 'N' or NOT exists(n.is_deleted))\n" +
                 "            OPTIONAL MATCH p=(m)-[]->(o) where head(Labels(m)) in [\"疾病\",\"症状\",\"药品通用名\",\"手术和操作\",\"实验室检查\",\"辅助检查\"]\n" +
                 "            RETURN head(Labels(n)) as sLabel,n.name as sName,Type (r) as rType, head(Labels(m)) as eLabel,m.name as eName, count(p) as pCount\n" +
                 "            ORDER BY rType";
 
-        try(Session session = Neo4jUtil.getSession()) {
+        try(Session session = neo4jUtil.getSession()) {
             StatementResult result = session.run(cypherQuery, Values.parameters("inputStr", kgQuery.getInputStr()));
             List<Map<String,Object>> listMap = new ArrayList<>();
             if(result.hasNext()) {
                 List<Record> records = result.list();
                 for (Record record : records) {
-//                    Map<String,Object> map = new HashMap<>();
-//                    Node node = record.get("n").asNode();
-//                    map.put("id", node.id());
-//                    map.put("labels", node.labels());
-//                    map.put("properties", node.asMap());
                     listMap.add(record.asMap());
                 }
             }

+ 3 - 1
src/main/java/com/qizhen/healsphere/web/dto/GNodeDTO.java

@@ -20,8 +20,9 @@ public class GNodeDTO {
     private String symbol;
     private Integer symbolSize;
     private Map<String, Object> properties;
+    private Long id;
 
-    public GNodeDTO(String type, Integer category, String label, Long name, String symbol, Integer symbolSize, Map<String, Object> properties) {
+    public GNodeDTO(String type, Integer category, String label, Long name, String symbol, Integer symbolSize, Map<String, Object> properties,Long id) {
         this.type = type;
         this.category = category;
         this.label = label;
@@ -29,5 +30,6 @@ public class GNodeDTO {
         this.symbol = symbol;
         this.symbolSize = symbolSize;
         this.properties = properties;
+        this.id = id;
     }
 }

+ 1 - 1
src/main/resources/application-test.yml

@@ -1,7 +1,7 @@
 spring:
   datasource:
     hikari:
-      driver-class-name: com.mysql.jdbc.Driver
+      driver-class-name: com.mysql.cj.jdbc.Driver
       username: root
       password: dsYun8!@#
       jdbc-url: jdbc:mysql://173.18.12.194:3306/sys-ltkg?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&characterSetResults=utf8&useSSL=false

+ 0 - 3
src/main/resources/application.properties.bak

@@ -1,3 +0,0 @@
-# 应用服务 WEB 访问端口
-server.port=8080
-

+ 6 - 2
src/main/resources/application.yml

@@ -1,5 +1,9 @@
 spring:
   profiles:
     active: local
-#  application:
-#    name: healsphere
+  application:
+    name: healsphere
+
+server:
+  servlet:
+    context-path: /healsphere