neo4j中的数据: 其中“王湘南”是主节点,它的关系有所属职称、工作单位、出生年份、论文作者、起草人员、完成人、所属学科、林业专家、培育人共9个。
但是使用语句
match (n)-[r*..2]-(m) where n.name="王湘南" return n,r,m limit 25
查询时,返回的结果如下:
结果中“王湘南”节点的直接关系只返回了培育人、工作单位、所属职称这3个,从数据上来看原因应该有两个,一是该cypher查询的是二层关系,从结果来看返回的第二层关系占用了限制数量的很大一部分;二是同一个关系名称返回了很多不同的节点,这也占用了限制数量的很大一部分。
如果不考虑层级的问题,neo4j能不能做到限制不同起始节点的同名关系返回的目标节点数量?
就这个问题使用apoc进行过一些尝试,但是结果不是很理想,我用的语句是这样的:
match (n)-[r]-(m) where n.name="王湘南"
with distinct type(r) as r0, n as n0
CALL apoc.cypher.run("with (r) as r,(n) as n match (n)-[r1:r]-(m1) return n,r1,m1 limit 1",{r:r0,n:n0}) YIELD value
return value.n,value.r1,value.m1
这个语句是模仿社区内的话题(http://neo4j.com.cn/topic/5c7e85b7cd4dafa110f1d03b)中最后提到的apoc语法改写的
第一行匹配“王湘南”这个节点和它的所有关系节点,第二行根据关系名称去重,第三行调用apoc,想要控制每个关系名称只返回一个目标节点,第四行返回apoc执行的结果,正常应该是能查到数据的,但是执行语句却查不到结果。
原因应该是第三行的r0参数没有传入到语句里面去,或者是语法不对。虽然知道问题在哪但是实在解决不了它,求助。。。
和朋友一起摸索改出了一版看起来达到了预期效果的语句,虽然执行的有点慢(命中79个节点171个关系,耗时4338毫秒),先记录一下
match (n)-[r*..3]-(m) where n.name="王湘南"
with distinct EXTRACT(rt in r | type(rt)) as r0, n as n0
CALL apoc.cypher.run("with (r) as r,(n) as n match (n)-[r1*..3]-(m1) where EXTRACT(rt in r1 | type(rt)) = r return n,r1,m1 limit 1",{r:r0,n:n0}) YIELD value
return value.n,value.r1,value.m1 order by size(value.r1) asc