ソースを参照

Merge remote-tracking branch 'origin/master'

SGTY 4 ヶ月 前
コミット
d4140126e0

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

@@ -44,7 +44,7 @@ public class KgServiceImpl implements KgService {
         map.put("inputStr",kgQuery.getInputStr());
         String cypherQuery = "MATCH (n:" + kgQuery.getLabelName() + ")-[r]->(m)\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" +
+                "            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";
 

+ 117 - 0
src/main/java/com/qizhen/healsphere/util/DrugRelationCreator.java

@@ -0,0 +1,117 @@
+package com.qizhen.healsphere.util;
+
+import cn.hutool.core.util.StrUtil;
+import com.qizhen.healsphere.config.Neo4jUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.neo4j.driver.v1.Record;
+import org.neo4j.driver.v1.Session;
+import org.neo4j.driver.v1.StatementResult;
+import org.neo4j.driver.v1.Values;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Pattern;
+
+@Slf4j
+@Component
+public class DrugRelationCreator {
+
+    @Autowired
+    private Neo4jUtil neo4jUtil;
+
+    private static final int BATCH_SIZE = 1000;
+    // 匹配中文字符的正则表达式
+    private static final Pattern CHINESE_PATTERN = Pattern.compile("[\\u4e00-\\u9fa5]+");
+    private static final int MIN_LENGTH = 3;
+
+    public void createDrugSubclassRelations() {
+        log.info("开始创建药品子类关系...");
+
+        try (Session session = neo4jUtil.getSession()) {
+            // 1. 获取所有药品节点
+            String queryDrugs = "MATCH (d:药品) RETURN d.name as name";
+            StatementResult result = session.run(queryDrugs);
+            
+            List<String> drugNames = new ArrayList<>();
+            while (result.hasNext()) {
+                Record record = result.next();
+                String name = record.get("name").asString();
+                // 过滤条件:非空、中文字符、长度大于3
+                if (isValidDrugName(name)) {
+                    drugNames.add(name);
+                }
+            }
+            
+            log.info("共找到 {} 个符合条件的药品节点", drugNames.size());
+            
+            // 2. 比较节点名称并创建关系
+            int count = 0;
+            for (int i = 0; i < drugNames.size(); i++) {
+                String drug1 = drugNames.get(i);
+                
+                for (int j = 0; j < drugNames.size(); j++) {
+                    if (i == j) continue;
+                    
+                    String drug2 = drugNames.get(j);
+                    
+                    // 如果drug1包含drug2,则drug1是drug2的父类
+                    if (drug1.contains(drug2)) {
+                        createSubclassRelation(session, drug2, drug1);
+                        count++;
+                        
+                        if (count % BATCH_SIZE == 0) {
+                            log.info("已处理 {} 条关系", count);
+                        }
+                    }
+                    // 如果drug2包含drug1,则drug2是drug1的父类
+                    else if (drug2.contains(drug1)) {
+                        createSubclassRelation(session, drug1, drug2);
+                        count++;
+                        
+                        if (count % BATCH_SIZE == 0) {
+                            log.info("已处理 {} 条关系", count);
+                        }
+                    }
+                }
+            }
+            
+            log.info("药品子类关系创建完成,共创建 {} 条关系", count);
+        } catch (Exception e) {
+            log.error("创建药品子类关系时发生错误", e);
+            throw new RuntimeException("创建药品子类关系失败", e);
+        }
+    }
+    
+    /**
+     * 判断药品名称是否有效
+     * 条件:
+     * 1. 非空
+     * 2. 包含中文字符
+     * 3. 长度大于3个字符
+     */
+    private boolean isValidDrugName(String name) {
+        if (StrUtil.isBlank(name) || name.length() < MIN_LENGTH) {
+            return false;
+        }
+        // 检查是否包含中文字符
+        return CHINESE_PATTERN.matcher(name).find();
+    }
+    
+    private void createSubclassRelation(Session session, String subDrug, String parentDrug) {
+        try {
+            String cypher = 
+                "MATCH (sub:药品 {name: $subName}), (parent:药品 {name: $parentName}) " +
+                "MERGE (sub)-[r:药品相关子类]->(parent) " +
+                "RETURN sub, parent, r";
+            
+            session.run(cypher, Values.parameters(
+                "subName", subDrug,
+                "parentName", parentDrug
+            ));
+        } catch (Exception e) {
+            log.error("创建关系时发生错误: {} -> {}", subDrug, parentDrug, e);
+        }
+    }
+} 

+ 9 - 2
src/test/java/com/qizhen/healsphere/MigrateDataTest.java

@@ -1,7 +1,6 @@
 package com.qizhen.healsphere;
 
 import cn.hutool.core.collection.CollectionUtil;
-import com.alibaba.fastjson.JSON;
 import com.qizhen.healsphere.repository.mapper.KgEdgesMapper;
 import com.qizhen.healsphere.repository.mapper.KgNodesMapper;
 import com.qizhen.healsphere.repository.mapper.KgSchemasMapper;
@@ -12,8 +11,8 @@ import com.qizhen.healsphere.repository.neo4j.BaseRelationshipRepository;
 import com.qizhen.healsphere.repository.neo4j.entity.BaseEntity;
 import com.qizhen.healsphere.repository.neo4j.entity.Edge;
 import com.qizhen.healsphere.util.DataMigrationUtil;
+import com.qizhen.healsphere.util.DrugRelationCreator;
 import com.qizhen.healsphere.util.IcdRelationCreator;
-import com.qizhen.healsphere.web.dto.RespDTO;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -47,6 +46,9 @@ public class MigrateDataTest {
     @Autowired
     private IcdRelationCreator icdRelationCreator;
 
+    @Autowired
+    private DrugRelationCreator drugRelationCreator;
+
     @Test
     public void migrateData() {
 
@@ -245,4 +247,9 @@ public class MigrateDataTest {
     public void createIcdRelations() {
         icdRelationCreator.createIcdRelations();
     }
+
+    @Test
+    public void createDrugSubclassRelations() {
+        drugRelationCreator.createDrugSubclassRelations();
+    }
 }