neo4j查询节点关联的有等级关系的节点数据,只取最高节点的数据,简化提数逻辑

本文介绍了如何在Neo4j数据库中处理复杂的数据提取需求,特别是涉及用户与类目层级关系的情况。通过创建和关联用户、类目及全量类目节点,然后使用Cypher查询语言,提取用户关联的最高级别类目数据,确保数据的简洁性和准确性。查询策略包括匹配不同级别的类目,并处理类目间的关系缺失情况,最后展示了正确的导出结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景

使用neo4j过程遇到的一个复杂提数需求

数据类型:pin是用户,category是用户关联的类目,类目分为一二三级类目,category之间还有关联,其中还有个象征全部的WildcardCategory节点(先不用理解)

数据逻辑:需要提取pin关联的全部类目数据,如果pin对有关系的类目都进行了关联,则取有关系类目中的最高级(级别依次降低顺序,1最高:1--》2--》3)数据表示,比如:如果pin同时关联了一级类目和二级类目,那么只记录关联的一级类目数据,目的简化要提取的数据情况。

数据演示过程

初始化数据cql

//创建用户
create (:Pin{name:"pin1"});

//创建类目
create (:Category{code:"11",level:1});
create (:Category{code:"12",level:1});
create (:Category{code:"13",level:1});

create (:Category{code:"21",level:2});
create (:Category{code:"22",level:2});
create (:Category{code:"221",level:2});
create (:Category{code:"23",level:2});
create (:Category{code:"24",level:2});

create (:Category{code:"31",level:3});
create (:Category{code:"32",level:3});
create (:Category{code:"33",level:3});
create (:Category{code:"331",level:3});
create (:Category{code:"34",level:3});

//创建代表全部类目的节点
create (:WildcardCategory{name:"category"});

//创建类目之间的关系
match (c1:Category),(c2:Category) where c1.code="11" and c2.code="21" create (c1)-[:IS_PARENT_OF]->(c2);
match (c1:Category),(c2:Category) where c1.code="21" and c2.code="31" create (c1)-[:IS_PARENT_OF]->(c2);
match (c1:Category),(c2:Category) where c1.code="12" and c2.code="22" create (c1)-[:IS_PARENT_OF]->(c2);
match (c1:Category),(c2:Category) where c1.code="12" and c2.code="221" create (c1)-[:IS_PARENT_OF]->(c2);
match (c1:Category),(c2:Category) where c1.code="22" and c2.code="32" create (c1)-[:IS_PARENT_OF]->(c2);
match (c1:Category),(c2:Category) where c1.code="13" and c2.code="23" create (c1)-[:IS_PARENT_OF]->(c2);
match (c1:Category),(c2:Category) where c1.code="23" and c2.code="33" create (c1)-[:IS_PARENT_OF]->(c2);
match (c1:Category),(c2:Category) where c1.code="23" and c2.code="331" create (c1)-[:IS_PARENT_OF]->(c2);

//创建用户和类目之间的关系
match (p:Pin),(c:Category) where p.name="pin1" and c.code in ["11","21","31","12","22","23","33","34"] create (p)-[:ALLOW]->(c);

//创建用户和全量类目的关系
match (p:Pin),(w:WildcardCategory) where p.name="pin1" create (p)-[:JOIN]->(w);

橘黄色是pin用户,蓝色是category类目,红色是全部类目节点,使用上面的语句可以初始化出来下面的数据情况

分析:不同红框内是要导出的不同数据,比如1、2、3都连的只导出1的数据,同时连1、2的只导出1,同时连2、3的只导出2,类目之间没有关联的单节点都导出,象征全部的节点也都导出。

导出cql

//查询关联一级类目的数据
match (p:Pin)-[:ALLOW]-(c:Category{level:1}) 
return distinct p.name as name,c.code as code,c.level as level,null as hasWildcardCategory order by p.name,c.level
union
//查询关联二级类目并且没有关联一级类目的数据
match (p:Pin)-[:ALLOW]-(c:Category{level:2})<-[:IS_PARENT_OF]-(cc:Category{level:1})
where not (p)-[:ALLOW]-(cc)
return distinct p.name as name,c.code as code,c.level as level,null as hasWildcardCategory order by p.name,c.level
union
//查询关联三级类目并且没有关联一、二级类目的数据
match (p:Pin)-[:ALLOW]-(c:Category{level:3})<-[:IS_PARENT_OF]-(cc:Category{level:2})<-[:IS_PARENT_OF]-(ccc:Category) 
where not (p)-[:ALLOW]-(cc) and not (p)-[:ALLOW]-(ccc)
return distinct p.name as name,c.code as code,c.level as level,null as hasWildcardCategory order by p.name,c.level
union
//数据兼容处理:可能存在一二三类目之间关系缺少的情况,查询没有关联任何上级类目的二三级类目
match (p:Pin)-[:ALLOW]-(c:Category)
where c.level in [2,3] and not (c)-[:IS_PARENT_OF]-(:Category)
return distinct p.name as name,c.code as code,c.level as level,null as hasWildcardCategory order by p.name,c.level
union
//查询用户是否关联了全部类目,因为是另外一种label,所以也需要查询出来
match (p:Pin)-[:JOIN]->(w:WildcardCategory)
return distinct p.name as name,null as code,null as level,"关联全部类目" as hasWildcardCategory

导出结果,完全正确,导出了pin关联的数据,也简化了导出的数据量

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值