我想在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)。
我怀疑,隐藏在某个地方的无限循环。
OS:Ubuntu 12.04.1 LTS服务器
Soft:neo4j-community-1.8.1
java版“1.7.0_10”(neo4j start表示使用JDK6)
Java(TM)SE运行时环境(版本1.7.0_10-b18)
Java HotSpot(TM)64位服务器VM(版本23.6-b04,混合模式)
编辑:匹配不正确应该是
MATCH n-[r1:LOVES]->friend-[r2:LOVES]->n
更新: 在纠正上面的语义之后,我仍然无法在5分钟内得到完整的结果。
LOVES是唯一的关系类型,约10-20%,或者关系有相应的关系。
我的最终目标是找到合适的Kiss值,以便我留下&lt; 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中没有有效的方法来查找反向关系的存在,这似乎是不可思议的。
答案 0 :(得分:1)
你应该在1.9中尝试这个 - cypher matcher已针对此类查询进行了显着优化。虽然避免节点(*)会很好。您的所有节点都是人吗?如果不是,您可能希望进行索引查询以仅获取相关人员节点。
start n=node:people("name:*")
...
答案 1 :(得分:1)
您可以尝试将friend
设为目标节点
START friend=node(*)
MATCH n-[r1:LOVES]->friend-[r2:LOVES]->n
WHERE r1.Kisses > 2 and r2.Kisses > 2
RETURN n, friend, r1, r2
LIMIT 20
你可以尝试将比赛分成两部分
START n=node(*)
MATCH n-[r1:LOVES]->friend
WHERE r1.Kisses > 2
WITH n,r1,friend
MATCH n<-[r2:LOVES]-friend
WHERE r2.Kisses > 2
RETURN n, friend, r1, r2
LIMIT 20
或者仅使用匹配执行查询的一半而使用过滤器执行后半部分
START n=node(*)
MATCH n-[r1:LOVES]->friend
WHERE r1.Kisses > 2
AND ALL(r2 in extract(
p in friend-[:LOVES]->n : head(rels(p)))
WHERE r2.Kisses > 2)
RETURN n, friend, r1
LIMIT 20
这是一个试用查询的控制台:http://console.neo4j.org/r/tqvb1p
但毕竟你正在处理3M节点,其匹配可能会爆炸到3M ^ 2