Neo4j 层次式查询在Cypher中的性能令人震惊。。我应该使用TraverserAPI吗?

Neo4j 层次式查询在Cypher中的性能令人震惊。。我应该使用TraverserAPI吗?,neo4j,cypher,Neo4j,Cypher,我的cypher查询如下(我希望找到在部门购买的用户) START n=node:sections('section\u ID:65,section\u ID:66…')//20个扇区 匹配(n)-[:HAS\u DOMAIN]->(dom)-[:HAS\u CAT]->(CAT)(用户) 返回n.sector\u name、COUNT(用户)、COLLECT(DISTINCT(product.name))、。。。等 我发现,因为在每次遍历中,路径的数量呈指数增长, 最终查询的结果时间为25秒

我的cypher查询如下(我希望找到在部门购买的用户)

START n=node:sections('section\u ID:65,section\u ID:66…')//20个扇区
匹配(n)-[:HAS\u DOMAIN]->(dom)-[:HAS\u CAT]->(CAT)(用户)
返回n.sector\u name、COUNT(用户)、COLLECT(DISTINCT(product.name))、。。。等
我发现,因为在每次遍历中,路径的数量呈指数增长, 最终查询的结果时间为25秒。 因此,也就是说,如果一个部门有50个域,那么每个域有1000个类别和每个类别 拥有250K++产品

在我看来,这就是“超级节点问题”。。。或者有太多的路径

我应该使用Traverser API吗? 我是否应该尝试以不同的方式对数据建模

欢迎有任何想法

Neo4j 1.8.3,Linux


谢谢

当您尝试加载所有路径时,您的主要问题实际上是内存问题。如果您需要的是统计数据,那么几乎可以肯定,使用Traverser API会更好,这样您就可以控制节点的加载/聚合方式

如果您想坚持使用Cypher,那么将每个扇区划分为自己的查询可能会有所帮助,这样它们就可以更好地并行运行。如果您完全控制了数据库的读/写,那么另一个选项是创建可以在读/写时更新的分类账节点。这样,您就不需要知道所有的路径,只需要知道这一变化如何影响统计数据。您还可以创建从扇区到感兴趣节点的直接关系,只需将所需信息收集到单个元素中,如

(sector)-[:HAS_CAT]->(cat)
WITH sector, collect(cat.name) as Categories

这样,每次匹配时,您都可以合并回原来的列数。

如果您使用
将查询一分为二,会有什么不同吗?我不认为我曾经使用过这样一个开放式模式进行查询,但我的感觉是分析内存使用情况,并与同一个被破坏的查询进行比较,类似于
..->(cat)with cat MATCH…
,因为我希望它在继续其他查询之前强制完成模式的前半部分的匹配。模糊预感警告买主。这里可能会发生很多事情-首先,你在扇区上做了大量的查找-每一个都可能需要1秒。你试过从用户那里搜索吗?所有购买了东西并根据现有关系导航回这些部门的用户?@Mike No,查找只需几毫秒(通过Lucene)。当路径成倍增加时,成本开始变大。不,我不能从用户开始,我想获得每个部门用户的汇总统计数据。@jjaderberg。我知道这会有什么帮助,因为相同的产品可以分为不同的类别。我会尝试一下,如果你有不必要的重复,你也可以尝试过滤这些早些时候。例如,较早地应用
DISTINCT(product)
可能会避免多次匹配同一产品中的同一组用户。
(sector)-[:HAS_CAT]->(cat)
WITH sector, collect(cat.name) as Categories