我想在 Neo4j DB 中找到一个只有强双向关系的子图。
假设关系是LOVES,属性是Kisses,那么我只想找到一个双方亲吻对方超过2次的子图。
START n=node(*)
MATCH n-[r1:LOVES]->friend<-[r2:LOVES]-n
WHERE r1.Kisses > 2 and r2.Kisses > 2
RETURN n, friend, r1, r2
LIMIT 20
问题是查询似乎在 3M 节点 30M 关系图、32GB RAM、四核系统上永远运行,neo4j 最大堆为 16GB(neo4j 计算器建议 8GB)。
我怀疑,某处隐藏着一个无限循环。
操作系统:Ubuntu 12.04.1 LTS 服务器
软:neo4j-community-1.8.1
java版本“1.7.0_10”(neo4j start 说使用JDK6)
Java(TM) SE 运行时环境 (build 1.7.0_10-b18)
Java HotSpot(TM) 64 位服务器 VM(内部版本 23.6-b04,混合模式)
编辑:匹配不正确,应该是
MATCH n-[r1:LOVES]->friend-[r2:LOVES]->n
更新:更正上述语义后,我仍然无法在 5 分钟内获得完整结果。
爱是唯一的关系类型,大约 10-20% 或关系有相应的另一种方式。
我的最终目标是找到合适的 Kiss 值,这样我就剩下 <100k 个节点(以及所有合适的 LOVES 关系)并且可以导出这个子图。
这是我正在尝试做的算法的伪代码:
let E be edge.list to be processed
let myedgelist be empty list
for e in E:
if e.n1 > e.n2: # so we do not look twice
continue
if not exist(e[n2][n1]): # this is where lookup can be a problem O(1) for hash, O(logn) for sorted, O(n) for something random)
continue
if e.kisses > 2 and e[n2][n1].kisses > 2:
add e to myedgelist
add e[n2][n1] to myedgelist
return myedgelist
该算法最多应该运行edgecount * log(edgecount),除非neo4j中没有有效的方法来查找反向关系的存在,这看起来相当不可思议。