分层样式查询在Cypher中具有令人震惊的性能.我应该使用Traverser API吗?

Nik*_*kos 7 neo4j cypher

我的密码查询如下(我希望找出已在部门购买的用户)

START n=node:sectors('SECTOR_ID:65, SECTOR_ID:66 ...') // 20 sectors  
MATCH (n)-[:HAS_DOMAIN]->(dom)-[:HAS_CAT]->(cat)<-[:BELONGS_TO]-(prod)-[:BOUGHT_BY]->(user)
RETURN n.sector_name, COUNT(user), COLLECT(DISTINCT(product.name)), ... etc.
Run Code Online (Sandbox Code Playgroud)

我发现因为在每次遍历时路径的数量呈指数增长,所以最终查询的结果时间为25秒.因此,即如果一个扇区有50个域,每个域有1000个类别,每个类别有250K ++产品.

在我看来,这是'超级节点问题'......或者路径太多了!

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

欢迎任何想法!

Neo4j 1.8.3,Linux

谢谢!

Tez*_*zra 0

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

如果您想坚持使用 Cypher,它可能有助于将每个扇区分解为它自己的查询,以便它们可以更好地并行运行。如果您可以完全控制数据库的读/写,那么另一个选择是创建可以在读/写时更新的账本节点。这样,您无需了解所有路径,只需了解这一更改如何影响统计信息即可。您还可以创建从部门到感兴趣的节点的直接关系,并将所需的信息收集到单个元素中,例如

(sector)-[:HAS_CAT]->(cat)
WITH sector, collect(cat.name) as Categories
Run Code Online (Sandbox Code Playgroud)

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