生产代码中的Mongoose索引

时间:2013-01-15 16:55:25

标签: node.js mongodb mongoose

对于MongooseJSMongoDB / Node.js,每个猫鼬documentation

  

当您的应用程序启动时,Mongoose会自动为您架构中的每个已定义索引调用ensureIndex。虽然很适合开发,但建议在生产中禁用此行为,因为创建索引会对性能产生重大影响。通过将架构的autoIndex选项设置为false来禁用该行为。

这似乎指示在部署之前从mongoose中删除自动索引以优化Mongoose,指示Mongo在应用程序启动时转到所有索引,这似乎是有意义的。

在生产代码中处理索引的正确方法是什么?也许外部脚本应该生成索引?或者,如果单个应用程序是集合的唯一读取器/写入器,则可能不需要ensureIndex,因为每次DB写入时它都会继续索引?

编辑:为了补充,MongoDB为 做索引提供了良好的documentation,但为什么何时应该显式索引指令。在我看来,编写器应用程序应该在具有现有索引的集合上自动更新索引,并且ensureIndex实际上更像是一次性事务(在应用新索引时完成),其中在正常的服务器重启下,Mongoose的autoIndex应该是无操作。

3 个答案:

答案 0 :(得分:112)

我从未理解为什么Mongoose文档如此广泛地建议在生产中禁用autoIndex。添加索引后,后续的ensureIndex调用将只看到索引已存在然后返回。因此,当您第一次创建索引时,它只对性能产生影响,并且此时集合通常为空,因此无论如何创建索引都会很快。

我的建议是启用autoIndex,除非您遇到麻烦的具体情况;就像你想要一个新的索引添加到一个拥有数百万个文档的现有集合,你想要更多地控制它的创建时间。

答案 1 :(得分:37)

虽然我同意接受的答案,但值得注意的是,根据MongoDB manual,这不是在生产服务器上添加索引的推荐方法:

  

如果您的应用程序包含ensureIndex()操作,并且其他操作问题不存在索引,那么构建索引会对数据库的性能产生严重影响。

     

为避免性能问题,请确保应用程序在启动时使用getIndexes()方法或驱动程序的等效方法检查索引,并在不存在正确的索引时终止。在指定的维护窗口期间,始终使用单独的应用程序代码在生产实例中构建索引。

当然,这实际上取决于您的应用程序的结构和部署方式。例如,如果您要部署到Heroku,并且您没有使用Heroku的preboot feature,那么很可能您的应用程序在启动期间根本没有提供请求,因此它可能会使用Heroku的create the index in the background。那时候创建索引可能是安全的。

除此之外,从接受的答案:

  

因此,当您首次创建索引时,它只对性能产生影响,并且此时集合通常为空,因此无论如何创建索引都会很快。

如果您第一次设法获取数据模型和查询,那么这很好,通常情况就是如此。但是,如果要向应用程序添加新功能,并在没有索引的属性上使用新的数据库查询,您通常会发现自己在包含许多现有文档的集合中添加索引。

这是您需要注意添加索引的时候,并仔细考虑这样做的性能影响。例如,您可以anatomy of model

db.ensureIndex({ name: 1 }, { background: true });

答案 2 :(得分:1)

使用此区块代码处理生产模式:

const autoIndex = process.env.NODE_ENV !== 'production';
mongoose.connect('mongodb://localhost/collection', { autoIndex });