neo4j 查询五度人脉的困惑
发布于 6 年前 作者 shziheyangde 4665 次浏览 来自 问答

刚接触neo4j, 在测试一个查询四度人脉和五度人脉的测试。 neo4j:rathat 4cores 24G neo4j社区版/企业版 Person 节点: 46W Friends 关系: 2300W

Person节点(把如下格式的csv导入neo4j,大约46W): personId:ID,name,Gender,city,:LABEL KZPE,KZPE,Male,珠海,Person VTFE,VTFE,Female,无锡,Person CTLS,CTLS,Female,武汉,Person friends关系(把如下格式的csv导入neo4j,大约2300W): :START_ID,role,:END_ID,:TYPE AAAA,emplyee,AAAA,friends AAAA,emplyee,ABAA,friends AAAA,emplyee,ACAA,friends

查询语句如下: match (a {name: ‘AAAA’})-[r1:friends]->()-[r2:friends]->()-[r3:friends]-> ()-[r4:friends]->(fof) return a.name,fof.name order by fof.name limit 100

需要30分钟才能查询出结果, 不知道什么原因,望各位大咖指教?

11 回复

数据量太大了,你可以用profile指令查看下 瓶颈,用法如下: profile match (a {name: ‘AAAA’})-[r1:friends]->()-[r2:friends]->()-[r3:friends]-> ()-[r4:friends]->(fof) return a.name,fof.name order by fof.name limit 100

另外补充一下给Person节点的name属性加上索引

算了下你构建的图平均每个节点有50条关系,关系数量多的话对从一个几点出发的expand效率影响挺大的。 你要的查询结果能否提前剪枝以减少遍历数量

@pangguoming 稍等时间有点长,一会上图。主要在Expand all操作符。 另外,相同的数据量,相同的需求, SQL SERVER 很快就查询出来了。

@zhoujieren64 ,太厉害了,我就是按照每个节点50个关系,创建的测试数据。

@pangguoming 大咖呀,正在拜读你的大作 “权威指南呢”

@pangguoming @zhoujieren64 是不是哪里的姿势不对,怎么在neo4j引以为豪的人脉深度的查询上,和关系数据库差好多。

这样返回的数据量巨大, 一般 节点关系 居多的情况下,使用shortestpath() 或者 allshotrestpath()来遍历查询两个人之间的人脉最短路径。 而不是这样全库遍历再海量数据查询返回

@shziheyangde profile的结果从图上你也可以看到你这样的查询会有多少的dbhits,如果没有应用场景你要这样去遍历的话其实真的不如直接在mysql里做4次join。 当你不知道人脉深度的时候或者不确定两者是否有关系的时候,这样的查询是关系数据库很难实现的

首先,要赞的是你贴了profile的结果。分析查询性能的一个重要手段就是explain/profile。下次可以把profile结果和问题一起发。

关于你的问题,有以下几点考虑:

  1. Cypher查询返回的是路径,而你需要的只是节点;返回路径要花费大量内存;
  2. 你看一下查询的执行时间、与结果在Browser中显示的时间做个对比。通常像这样返回大量数据的查询会在客户端消耗大量时间;
  3. 考虑一下你的应用场景:什么情况下需要返回6百多万节点?是否必须按照姓名排序?如果可以随机选择,可以更快返回节点;
  4. 数据库配置是怎样的?方便发neo4j.conf上来吗?
  5. 如果仅作为测试,你生成数据集的方式无可厚非;但是在实际的社交网络中,通常遵循"Small world network"规律,即节点的连接数是幂律分布、而非平均分布。

如果只需要节点、不需要路径,建议使用apoc.path.subgraphNodes。

回到顶部