如何使用 neo4j.Apoc 执行子模式匹配?

How to perform sub pattern matches with neo4j.Apoc?

我有疑问:

MATCH (a:vertex {label: 'a'})<-->(b:vertex {label: 'b'})
MATCH (a)<-->(e:vertex {label: 'e'})
MATCH (b)<-->(c:vertex {label: 'c'})
MATCH (b)<-->(e:vertex {label: 'e'})
MATCH (c)<-->(d:vertex {label: 'd'}) 
MATCH (d)<-->(e)
MATCH (d)<-->(a)
return a,b,c,d,e

还有一个包含 50.000 个顶点和 10.000.000 条边的图。 总共只有a,b,c,d,e,f标签,我知道这个匹配存在

我已经安装了 neo4j.apoc 插件以便在我的机器上使用 8 个内核,并且我已经尝试了以下查询:

CALL apoc.periodic.iterate(
"MATCH (a:vertex {label: 'a'})<-->(b:vertex {label: 'b'})
MATCH (a)<-->(e:vertex {label: 'e'})
MATCH (b)<-->(c:vertex {label: 'c'})
MATCH (b)<-->(e:vertex {label: 'e'})
MATCH (c)<-->(d:vertex {label: 'd'}) 
MATCH (d)<-->(e)
MATCH (d)<-->(a)
return a,b,c,d,e",
"return DISTINCT([ID(a),ID(b),ID(c),ID(d),ID(e)]) AS LIST", {batchSize:10000, parallel:true})

这个查询只使用了几个核心,它基本上不会 returns 结果,它只是永远处理。我一直在看 函数 apoc.path.subgraphAll(startNode <id>Node/list, {maxLevel, relationshipFilter, labelFilter, bfs:true, filterStartNode:true, limit:-1}) yield nodes, relationships

但是由于我对 NEO4J 当然还有 Apoc 很陌生,所以我实际上不明白如何填写这些关系。有没有人知道这些东西并且可以指出我正确的方向?

编辑:我有一个自定义的 java 图实现,它并行执行此操作并在大约 600 毫秒内完成,我期待 NEO4J 更快地完成它,但因为查询只使用 1 个线程,它需要很长时间,这就是为什么我一直在研究 Apoc。我也愿意使用 Apoc 之外的其他东西,也许我的查询可以只使用 NEO4J 进行优化并更快地完成。我在 :vertex(label) 上创建了一个索引,所以至少那部分会进行索引查找。

编辑2: 这个查询应该做同样的事情,而且显然更漂亮:

CALL apoc.periodic.iterate(
"MATCH (a:vertex {label:'a'})--(b:vertex {label: 'b'})--(c:vertex {label: 'c'})--(d:vertex {label: 'd'})--(e:vertex {label: 'e'}) WHERE (c)<-->(d) AND (b)--(e) AND (d)--(a) 
RETURN a,b,c,d,e",
"return DISTINCT([ID(a),ID(b),ID(c),ID(d),ID(e)]) AS LIST", {batchSize:10000, parallel:true})

但它仍然从未停止处理,我什至将图形调整为 10k 个顶点和 500 万个边。

为此我不需要 Apoc,我误解了密码语法,我认为 (a)<-->(b) 意味着 a 和 b 需要双向关系。但实际上只是匿名关系。 所以我把它优化成这样:

MATCH (a:vertex {label:'a'})-->(b:vertex {label: 'b'})-->(c:vertex {label: 'c'})-->(d:vertex {label: 'd'})-->(e:vertex {label: 'e'}) WHERE (d)-->(a) AND (b)-->(e) AND (d)-->(e)  WITH a,b,c,d,e
MATCH (a)<--(b)<--(c)<--(d)<--(e:vertex {label: 'e'}) WHERE (d)<--(a) AND (b)<--(e) AND (d)<--(e)  WITH a,b,c,d,e
return DISTINCT([ID(a),ID(b),ID(c),ID(d),ID(e)])

为了过滤指向两个方向的边,使查询计划中的估计行数大大减少,现在在 12000 毫秒内完成