基于Gremlin查询关联Code数量最多的Top2 Patient节点及路径
Gremlin查询解决方案:找出关联Code最多的Top2 Patient节点
一、示例数据插入语句
先执行以下语句生成测试用图结构,包含Patient、Diagnosis、Code三类顶点及关联边:
// 插入Patient顶点 g.addV('Patient').property('id', 'P1').property('name', '张三') g.addV('Patient').property('id', 'P2').property('name', '李四') g.addV('Patient').property('id', 'P3').property('name', '王五') g.addV('Patient').property('id', 'P4').property('name', '赵六') // 插入Diagnosis顶点 g.addV('Diagnosis').property('id', 'D1').property('disease', '糖尿病') g.addV('Diagnosis').property('id', 'D2').property('disease', '高血压') g.addV('Diagnosis').property('id', 'D3').property('disease', '冠心病') // 插入Code顶点 g.addV('Code').property('id', 'C1').property('code', 'ICD-10-E11') g.addV('Code').property('id', 'C2').property('code', 'ICD-10-I10') g.addV('Code').property('id', 'C3').property('code', 'ICD-10-I25') g.addV('Code').property('id', 'C4').property('code', 'ICD-10-E10') g.addV('Code').property('id', 'C5').property('code', 'ICD-10-I11') // 插入Patient到Diagnosis的边 g.V('P1').addE('HAS_DIAGNOSIS').to(g.V('D1')) g.V('P1').addE('HAS_DIAGNOSIS').to(g.V('D2')) g.V('P2').addE('HAS_DIAGNOSIS').to(g.V('D1')) g.V('P2').addE('HAS_DIAGNOSIS').to(g.V('D2')) g.V('P2').addE('HAS_DIAGNOSIS').to(g.V('D3')) g.V('P3').addE('HAS_DIAGNOSIS').to(g.V('D1')) g.V('P4').addE('HAS_DIAGNOSIS').to(g.V('D3')) // 插入Code到Diagnosis的边 g.V('C1').addE('MAPS_TO').to(g.V('D1')) g.V('C4').addE('MAPS_TO').to(g.V('D1')) g.V('C2').addE('MAPS_TO').to(g.V('D2')) g.V('C5').addE('MAPS_TO').to(g.V('D2')) g.V('C3').addE('MAPS_TO').to(g.V('D3'))
二、目标查询语句
以下查询会完成:遍历Patient->Diagnosis<-Code路径、统计每个Patient关联的唯一Code数量、过滤仅关联1个Code的Patient、按Code数量降序取Top2,同时返回关联的顶点和边属性:
g.V().hasLabel('Patient') .as('patient') // 遍历到关联的Diagnosis,再跳转至关联的Code .out('HAS_DIAGNOSIS').in('MAPS_TO') .dedup() // 去重同一Patient关联的重复Code .groupCount().by(select('patient')) .unfold() // 过滤掉仅关联1个Code的Patient .filter(select(values).is(gt(1))) // 按Code数量降序排序,取前2位 .order().by(values, desc) .limit(2) // 结构化返回结果:Patient属性、Code数量、关联的所有顶点和边 .project('patient_info', 'code_count', 'related_elements') .by(select(keys).valueMap(true)) .by(select(values)) .by( select(keys) .outE('HAS_DIAGNOSIS').as('patient_diagnosis_edge') .inV().as('diagnosis') .inE('MAPS_TO').as('code_diagnosis_edge') .outV().as('code') .select('patient', 'patient_diagnosis_edge', 'diagnosis', 'code_diagnosis_edge', 'code') .dedup() )
如果仅需要Patient基础信息和Code数量,可简化为:
g.V().hasLabel('Patient') .as('patient') .out('HAS_DIAGNOSIS').in('MAPS_TO').dedup() .groupCount().by(select('patient')) .unfold() .filter(select(values).is(gt(1))) .order().by(values, desc).limit(2) .project('patient_id', 'patient_name', 'code_count') .by(select(keys).values('id')) .by(select(keys).values('name')) .by(select(values))
三、关键逻辑说明
- 去重处理:
dedup()避免同一Patient因重复关联Diagnosis或同一Diagnosis关联多Code导致的重复统计。 - 过滤条件:
filter(select(values).is(gt(1)))直接排除仅关联1个Code的Patient。 - 排序取Top2:通过
order().by(values, desc).limit(2)实现按关联Code数量降序筛选前两位。
内容的提问来源于stack exchange,提问作者Dee
相关产品推荐
相关产品推荐

