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


124

Согласно документации Mongoose для MongooseJSи MongoDB/ Node.js:

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

Похоже, что это указывает на удаление автоматической индексации из мангуста перед развертыванием, чтобы оптимизировать Mongoose от указания Mongo пройти и перебрать все индексы при запуске приложения, что, кажется, имеет смысл.

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

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

Ответы:


135

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

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


10
У меня есть вопрос, который нужно добавить ... Что, если я поставлю false? Чем будут созданы индексы, когда я вставлю данные, или мне нужно будет создать их явно. Прошу прощения, если это вопрос новичка, но было бы очень полезно, если бы вы ответили.
Саранш Мохапатра

5
@SaranshMohapatra Если задано значение autoIndexfalse, вам необходимо вызвать в модели sureIndexes для создания ее индексов.
JohnnyHK

Чем мне придется называть это каждый раз или только один раз, определяя модель?
Саранш Мохапатра

@SaranshMohapatra, когда вы определяете (компилируете) свою модель. Я делаю это, когда впервые запускаю приложение. Теперь сложнее всего решить удалить все индексы и воссоздать их, если вы измените схему.
Moss

3
@JohnnyHK, вы все еще согласны со своим ответом, ведь сейчас почти 2016 год?
Александр Миллс

41

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

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

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

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

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

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

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

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

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

3
Хорошо, поэтому все, что вам нужно сделать, это НЕ запускать сервер до тех пор, пока не будут запущены все обратные вызовы sureIndex для каждой коллекции.
Александр Миллс

@AlexMills, как вы это обеспечиваете?
lonelymo

async.each (Object.keys (models), function (key, cb) {models [key] .ensureIndexes (cb)}, cb)
Александр Миллс

просто вызовите sureIndexes для каждой модели мангуста, дождитесь завершения всех операций и запустите сервер; Я также рекомендую дождаться подключения к базе данных, прежде чем запускать ваш сервер,
Александр Миллс,

2
Больше нет ensureIndex. Существует createIndexвместо этого. Я прав?
jack blank

1

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

const autoIndex = process.env.NODE_ENV !== 'production';
mongoose.connect('mongodb://localhost/collection', { autoIndex });
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.