node.js 生产代码中的猫鼬索引

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14342708/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 16:57:30  来源:igfitidea点击:

Mongoose indexing in production code

node.jsmongodbmongoose

提问by Nick S.

Per the Mongoose documentationfor MongooseJSand MongoDB/Node.js:

每猫鼬文档MongooseJSMongoDB/ Node.js

When your application starts up, Mongoose automatically calls ensureIndexfor each defined index in your schema. While nice for development, it is recommended this behavior be disabled in production since index creation can cause a significant performance impact. Disable the behavior by setting the autoIndexoption of your schema to false.

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

This appears to instruct removal of auto-indexing from mongoose prior to deploying to optimize Mongoose from instructing Mongo to go and churn through all indexes on application startup, which seems to make sense.

这似乎指示在部署之前从 mongoose 中删除自动索引以优化 Mongoose,从而指示 Mongo 在应用程序启动时去和搅动所有索引,这似乎是有道理的。

What is the proper way to handle indexing in production code? Maybe an external script should generate indexes? Or maybe ensureIndexis unnecessary if a single application is the sole reader/writer to a collection because it will continue an index every time a DB write occurs?

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

Edit:To supplement, MongoDB provides good documentationfor the howto do indexing, but not whyor whenexplicit indexing directives should be done. It seems to me that indexes should be kept up to date by writer applications automatically on collections with existing indexes and that ensureIndexis really more of a one-time thing (done when a new index is being applied), in which case Mongoose's autoIndexshould be a no-op under a normal server restart.

编辑:补充,MongoDB中提供了良好的文档如何做索引,但不为什么还是明确索引指令应该做的。在我看来,索引应该由作家应用程序自动在具有现有索引的集合上保持最新,这ensureIndex实际上更多是一次性的事情(在应用新索引时完成),在这种情况下,猫鼬autoIndex应该是在正常服务器重启下无操作。

回答by JohnnyHK

I've never understood why the Mongoose documentation so broadly recommends disabling autoIndexin production. Once the index has been added, subsequent ensureIndexcalls will simply see that the index already exists and then return. So it only has an effect on performance when you're first creating the index, and at that time the collections are often empty so creating an index would be quick anyway.

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

My suggestion is to leave autoIndexenabled unless you have a specific situation where it's giving you trouble; like if you want to add a new index to an existing collection that has millions of docs and you want more control over when it's created.

我的建议是保持autoIndex启用状态,除非您遇到了给您带来麻烦的特定情况;例如,如果您想向拥有数百万文档的现有集合添加新索引,并且希望对其创建时间进行更多控制。

回答by Tom Spencer

Although I agree with the accepted answer, its worth noting that according to the MongoDB manual, this isn't the recommended way of adding indexes on a production server:

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

If your application includes ensureIndex() operations, and an index doesn't exist for other operational concerns, building the index can have a severe impact on the performance of the database.

To avoid performance issues, make sure that your application checks for the indexes at start up using the getIndexes() method or the equivalent method for your driver and terminates if the proper indexes do not exist. Always build indexes in production instances using separate application code, during designated maintenance windows.

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

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

Of course, it really depends on how your application is structured and deployed. If you are deploying to Heroku, for example, and you aren't using Heroku's preboot feature, then it is likely your application is not serving requests at all during startup, and so it's probably safe to create an index at that time.

当然,这实际上取决于您的应用程序的结构和部署方式。例如,如果您正在部署到 Heroku,并且您没有使用 Heroku 的预引导功能,那么您的应用程序可能在启动期间根本不处理请求,因此此时创建索引可能是安全的。

In addition to this, from the accepted answer:

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

So it only has an effect on performance when you're first creating the index, and at that time the collections are often empty so creating an index would be quick anyway.

因此,它仅在您第一次创建索引时对性能产生影响,并且那时集合通常是空的,因此无论如何创建索引都会很快。

If you've managed to get your data model and queries nailed on first time around, this is fine, and often the case. However, if you are adding new functionality to your app, with a new DB query on a property without an index, you'll often find yourself adding an index to a collection containing many existing documents.

如果您第一次就成功地确定了数据模型和查询,那很好,而且经常是这种情况。但是,如果您要向应用程序添加新功能,并在没有索引的属性上使用新的数据库查询,您经常会发现自己向包含许多现有文档的集合添加索引。

This is the time when you need to be careful about adding indexes, and carefully consider the performance implications of doing so. For example, you could create the index in the background:

此时您需要小心添加索引,并仔细考虑这样做对性能的影响。例如,您可以在后台创建索引

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

回答by Masih Jahangiri

use this block code to handle production mode:

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

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