3

我想在 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中没有有效的方法来查找反向关系的存在,这看起来相当不可思议。

4

2 回答 2

1

您应该在 1.9 中尝试这一点——密码匹配器已针对此类查询进行了显着优化。尽管避免使用节点(*)会很好。你所有的节点都是人吗?如果不是,您可能想要进行索引查询以仅获取相关的人员节点。

start n=node:people("name:*")...

于 2013-01-04T16:47:49.037 回答
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

于 2013-01-04T18:18:04.750 回答