Индексирование Mongoose в производственном коде

В файле Mongoose для MongooseJS и MongoDB/Node.js:

Когда приложение запускается, Mongoose автоматически вызывает ensureIndex для каждого определенного индекса в вашей схеме. Хотя это хорошо для разработки, рекомендуется, чтобы это поведение было отключено в процессе производства, поскольку создание индекса может привести к значительным результатам. Отключите поведение, установив для параметра autoIndex вашей схемы значение false.

Это, как представляется, дает указание удалить автоматическую индексацию из mongoose до развертывания, чтобы оптимизировать Mongoose от инструктирования Mongo, чтобы пойти и опрокинуть все индексы при запуске приложения, что, по-видимому, имеет смысл.

Каков правильный способ обработки индексирования в производственном коде? Может быть, внешний script должен генерировать индексы? Или, может быть, ensureIndex не нужно, если одно приложение является единственным читателем/писателем для коллекции, потому что оно будет продолжать индексировать каждый раз, когда происходит запись БД?

Изменить: В дополнение, MongoDB предоставляет хорошую документацию для того, как делать индексацию, но не почему и когда должны быть указаны явные директивы индексирования. Мне кажется, что индексы должны постоянно обновляться приложениями-писателями автоматически на коллекциях с существующими индексами и что ensureIndex действительно больше одноразового использования (выполняется при применении нового индекса), и в этом случае Mongoose autoIndex должен быть no-op при обычном перезагрузке сервера.

Ответ 1

Я никогда не понимал, почему документация Mongoose так широко рекомендует отключать autoIndex в производстве. Как только индекс будет добавлен, последующие вызовы ensureIndex просто увидят, что индекс уже существует и затем возвращается. Таким образом, это только влияет на производительность при первом создании индекса, и в то время коллекции часто пустые, поэтому создание индекса в любом случае будет быстрым.

Мое предложение оставить autoIndex включенным, если у вас нет конкретной ситуации, когда это создает проблемы; например, если вы хотите добавить новый индекс в существующую коллекцию, в которой есть миллионы документов, и вы хотите больше контролировать ее создание.

Ответ 2

Хотя я согласен с принятым ответом, стоит отметить, что в соответствии с руководством MongoDB это не рекомендуется для добавления индексов на производственный сервер:

Если ваше приложение включает операции sureIndex(), а индекс не существует для других операционных проблем, создание индекса может оказать серьезное влияние на производительность базы данных.

Чтобы избежать проблем с производительностью, убедитесь, что ваше приложение проверяет индексы при запуске с использованием метода getIndexes() или эквивалентного метода для вашего драйвера и завершает работу, если соответствующие индексы не существуют. Всегда создавайте индексы в производственных экземплярах с использованием отдельного кода приложения во время определенных окон обслуживания.

Конечно, это действительно зависит от того, как ваше приложение структурировано и развернуто. Например, если вы развертываете в Heroku, и вы не используете функцию Heroku preboot, то, скорее всего, ваше приложение не будет выполнять запросы вообще во время запуска, и поэтому, возможно, безопасно создать индекс в то время.

В дополнение к этому из принятого ответа:

Таким образом, это только влияет на производительность при первом создании индекса, и в то время коллекции часто пустые, поэтому создание индекса в любом случае будет быстрым.

Если вам удалось впервые получить модель данных и запросы, прибитые в первый раз, это нормально, и часто бывает так. Однако, если вы добавляете новые функции в свое приложение, с новым запросом БД на свойство без индекса, вы часто обнаружите, что добавляете индекс в коллекцию, содержащую многие существующие документы.

Это время, когда вам нужно быть осторожным с добавлением индексов и тщательно учитывать последствия этого для производительности. Например, вы можете создать индекс в фоновом режиме:

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

Ответ 3

используйте этот код блока для обработки производственного режима:

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