背景:
使用图数据neo4j的cypher语法,查询如下图的一个关系
想要的结果
name1 | name2 | name3 |
name4 | name5 | null |
name6 | null | null |
分析:
使用这个语句,一直查询出来的结果如下:
match (d:Category{level:1})-[:IS_PARENT_OF]->(dd:Category{level:2})-[:IS_PARENT_OF]->(ddd:Category{level:3})
return d.name,d.code,dd.name,dd.code,ddd.name,ddd.code
order by d.code,dd.code,dd.code
也就是只有一二三级类目关系都存在时,才能正常查询返回,如果中间有一个不存在,则一个关系都不返回,所以只能查询出来如下一种情况
name1 | name2 | name3 |
初始化测试数据
//创建类目
create (:Category{code:"11",level:1});
create (:Category{code:"12",level:1});
create (:Category{code:"13",level:1});
create (:Category{code:"14",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});
//创建类目之间的关系
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);
初始化结果
正确应该导出六条数据
解决办法
方法一:正确
//方法一,使用这种办法
optional match (d:Category{level:1})
with d
optional match (d)-[:IS_PARENT_OF]->(dd:Category{level:2})
with d,dd
optional match (dd)-[:IS_PARENT_OF]->(ddd:Category{level:3})
return d.level,d.code,dd.level,dd.code,ddd.level,ddd.code
order by d.code,dd.code,dd.code
导出结果一,六条正确
方法二:错误
//方法二,不行
optional match (d:Category{level:1})-[:IS_PARENT_OF]->(dd:Category{level:2})-[:IS_PARENT_OF]->(ddd:Category{level:3})
return d.level,d.code,dd.level,dd.code,ddd.level,ddd.code
order by d.code,dd.code,dd.code
导出结果二,四条,只有前面节点没有后续节点的数据都过滤了,这个语句可以查询全部正常的数据,不适合当前的场景。