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

时间:2013-10-21 17:40:11

标签: 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.

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

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

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

欢迎任何想法!

Neo4j 1.8.3,Linux

谢谢!

1 个答案:

答案 0 :(得分:0)

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

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

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

这样,对于每个匹配,您可以合并回原始列数。