Neo4j遍历节点以提高查询性能

时间:2018-10-08 16:50:14

标签: performance loops neo4j cypher

我正在研究Neo4j上的一个项目。我大约有100万个节点和400万个关系。

当我尝试执行查询时,大约需要15秒才能得到结果。我还在email.createdAt

上设置了索引

查询如下:

MATCH (email:Email) 
WITH email 
ORDER BY email.createdAt 
WHERE email.body CONTAINS "word" 
RETURN email 
SKIP 0 
LIMIT 10

所以,我试图弄清楚如何才能改善切割效果以及获得结果所需的时间。

到目前为止,我有一个主意,但我不知道是否可能。

我认为查询必须是这样的:

  • 带所有按日期DESC订购的电子邮件
  • 遍历每个电子邮件节点(desc)在email.body中搜索“单词”
  • 当它有10个匹配项时,它将停止并仅返回那10封电子邮件。

主要思想不是循环遍历所有节点,而是仅需要查找前10个匹配项。也许使用Unwind,对于For Each,我不知道。

有人对如何编写此查询有想法吗?谢谢你们!

1 个答案:

答案 0 :(得分:1)

在大多数情况下,您应该使查询尽可能简短。 Neo4j Cypher计划器功能非常强大,并且通过尝试对其进行微管理,会阻碍其使用最佳计划。

在您的情况下,开始Match (email:Email) With email基本上迫使计划程序加载所有电子邮件节点(因为WITH在密码中创建了逻辑分区),并且计划程序当时无法真正优化,因为您已经已经将其锁定为最差的性能(因为它只是从那里进行过滤)。

一个更好的Cypher看起来像这样

Match (email:Email) 
Where email.body Contains "word" 
Return email Order by email.createdAt Skip 0 Limit 10

基本相同,但是没有显微管理WITH部分。 WHERE是唯一可以更改加载节点的部分,因此,通过这样做,计划程序可以在扫描createdAt索引时找到10个符合条件的节点之后停止运行。

通常,除非您想成为Neo4j DB专家,否则最好的密码通常是您可以编写的最简单的密码,并在关键字段上具有索引。