向密码查询添加属性过滤器会爆炸内存,为什么?

时间:2019-04-19 08:00:03

标签: neo4j cypher

我正在尝试编写一个查询,该查询针对与给定产品关联的所有零件中的所有构造路径,探索DAG类型图(材料明细表),直至所有特定零件编号(第二个MATCH)(第一次比赛)。有一种我不理解的奇怪行为:

此查询使用Neo4j社区版(〜2 s)在合理的时间内运行:

WITH '12345' as snid, 'ABCDE' as pid
MATCH (m:Product {full_sn:snid})-[:uses]->(p:Part)
WITH snid, pid, collect(p) AS mparts
MATCH path=(anc:Part)-[:has*]->(child:Part)
WHERE ALL(node IN nodes(path) WHERE node IN mparts)
WITH snid, path, relationships(path)[-1] AS rel, 
nodes(path)[-2] AS parent, nodes(path)[-1] AS child
RETURN stuff I want

但是,要获取我想要的查询,我必须使用第二个MATCH语句中的部件号pid在子项上添加一个过滤器:

MATCH path=(anc:Part)-[:has*]->(child:Part {pn:pid})

当我尝试运行新查询时,neo4j浏览器显示内存不足。 (Neo.TransientError.General.OutOfMemoryError)。当我使用EXPLAIN运行它时,数据库命中数激增至数十亿,就好像我要它提供大型的cartestian产品一样:但是我所做的只是增加了对孩子的限制,因此这应该减少搜索空间,不是吗?

我还尝试在:Part(pn)上添加索引。现在EXPLAIN显示的配置文件看起来非常有效,但是我仍然遇到相同的内存错误。

如果有人可以帮助我理解为什么两个查询之间的这种变化会引起问题,我将不胜感激!

最良好的祝愿

1 个答案:

答案 0 :(得分:0)

MATCH path=(anc:Part)-[:has*]->(child:Part)

*爆炸到每个下游子节点。 如果需要的话,那是适当的。如果将此作为可选匹配项并限制为收集项目,则这将限制返回结果。

   OPTIONAL MATCH path=(anc:Part)-[:has*]->(child:Part)

从概念上讲(和在本质上)类似于SQL中的内部联接。