Pymongo / MongoDB: создать индекс или обеспечить индекс? - PullRequest
48 голосов
/ 06 мая 2011

Я не понимаю разницу между create_index и ensure_index в пимонго. На странице MongoDB indexes написано

вы можете создать индекс, вызвав ensureIndex()

Однако в pymongo есть две разные команды create_index и ensure_index, и документация для создания индекса имеет:

В отличие от create_index (), который пытается безоговорочно создать индекс, sure_index () использует преимущества некоторых кэширование в драйвере, так что это только попытки создать индексы, которые может не существовать Когда индекс создается (или гарантируется) PyMongo это «запоминается» на ttl секунд. Повторные вызовы sure_index () в течение этого времени будет легкий - они не будут пытаться на самом деле создать индекс.

Правильно ли я понимаю, что ensure_index создаст постоянный индекс или мне нужно использовать create_index для этого?

Ответы [ 5 ]

39 голосов
/ 06 мая 2011

@ andreas-jung прав в том, что ensure_index() является оберткой над create_index(), я думаю, что путаница возникает с фразой:

Когда индекс создается (или обеспечивается)PyMongo «запоминается» на ttl секунд.

Дело не в том, что индекс является временным или «временным», что происходит в том случае, если в течение указанного количества секунд, вызов ensure_index() пытаетсяповторное создание того же индекса не окажет какое-либо влияние и не вызов create_index() внизу, но после истечения срока действия «кэша» вызов ensure_index() будет снова позвоните create_index() внизу.

Я прекрасно понимаю вашу путаницу, потому что, честно говоря, документы PyMongo не очень хорошо объясняют, как это работает, но если вы перейдете к Rubyдокументы , объяснение немного понятнее:

  • (String) sure_index (spec, opts = {})

Вызывает create_index и устанавливаетфлаг, чтобы не делать это снова в течение еще X минут.это время можно указать в качестве опции при инициализации объекта Mongo :: DB в качестве параметров [: cache_time]. Любые изменения индекса будут распространяться независимо от времени кэширования (например, изменение направления индекса)

Параметры и параметры для этих методов те же, что и для Collection # create_index.

Примеры:

Call sequence:

Time t: @posts.ensure_index([['subject', Mongo::ASCENDING]) -- calls create_index and sets the 5 minute cache

Time t+2min : @posts.ensure_index([['subject', Mongo::ASCENDING]) -- doesn't do anything

Time t+3min : @posts.ensure_index([['something_else', Mongo::ASCENDING]) -- calls create_index and sets 5 minute cache

Time t+10min : @posts.ensure_index([['subject', Mongo::ASCENDING]) -- calls create_index and resets the 5 minute counter

Я не утверждаю, что драйверы работают точно так же, просто в целях иллюстрации их объяснениенемного лучше ИМХО.

14 голосов
/ 19 мая 2015

Имейте в виду, что в Mongo 3.x verifyIndex устарело и его не рекомендуется использовать.

Не рекомендуется с версии 3.0.0: db.collection.ensureIndex ()теперь псевдоним для db.collection.createIndex ().

То же самое в pymongo :

DEPRECATED - Гарантирует, что индекс существуетэта коллекция.

Это означает, что вы всегда должны использовать create_index.

9 голосов
/ 11 мая 2012

Метод ensureIndex в Interactive Shell и ensure_index в драйвере питона - разные вещи, хотя используется одно и то же слово.И метод create_index, и ensure_index из драйвера python постоянно создают индекс.

Возможно, в такой ситуации можно использовать ensure_index с приемлемым TTL, потому что я не уверен, что create_indexбудет воссоздавать индекс каждый раз, когда вы вызываете его.Отдых обычно не желателен, и это может быть тяжелой операцией.Но даже ensure_index (из драйвера python или драйвера ruby) может воссоздать индекс всякий раз, когда истекает TTL, или когда вы вызываете его из другого экземпляра клиента или после перезапуска.Я не уверен в этом.

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

Сейчас я демонстрирую, как термин ensure_index (или ensureIndex) используется в двух разных значениях:

1) Он создает индекс, если он еще не существует в базе данных

Это то, что Interactive Shell метод ensureIndex() делает:

http://www.mongodb.org/display/DOCS/Indexes#Indexes-Basics

Также Node.JS MongoDB Driver ведет себя так:

https://github.com/mongodb/node-mongodb-native/blob/master/lib/mongodb/collection.js

(Поиск function ensureIndex в файле collection.js.)

2) Он создает индекс, если его нет в «кэше драйверов»

Этот же идентификатор используется здесь с другим значением, что я нахожу запутанным.

Питон и драйвер ruby ​​хранят в памяти информацию об индексах, которые были созданы недавно, и они называют это поведение «кэшированием».

Они не сообщают базе данных об этом кешировании.

Результат этого механизма: если вы в первый раз вызываете create_index или ensure_index со значением TTL (время жизни), драйвер вставит индекс в базу данных и запомнитэта вставка, а также хранить информацию TTL в памяти.Здесь кешируется время и индекс, в котором оно было.

При следующем вызове ensure_index с тем же индексом из той же коллекции в том же экземпляре драйвера команда ensure_index вставит толькоПовторите индексирование, если TTL-секунды еще не прошли с момента первого вызова.

Если вы наберете create_index, индекс будет вставлен всегда, независимо от того, сколько времени прошло с момента первого вызова, и, конечно, такжеесли это первый вызов.

Это драйвер python, найдите def ensure_index в файле collection.py:

https://github.com/mongodb/mongo-python-driver/blob/master/pymongo/collection.py

И драйвер ruby, найдите def ensure_index в файле collection.rb:

https://github.com/mongodb/mongo-ruby-driver/blob/master/lib/mongo/collection.rb

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

Iбыл еще не в состоянии полностьюпонять, что происходит в БД, когда драйвер python или драйвер ruby ​​вставляют индекс, который уже существует.Я подозреваю, что в этом случае они ничего не делают, что имеет больше смысла, а также соответствует поведению Interactive Shell и драйвера JS.

3 голосов
/ 06 мая 2011

Все индексы являются постоянными. sure_index () - это просто крошечная оболочка для create_index ().

""» Функция sureIndex () создает индекс только в том случае, если он не существует. "" "

Нет ничего похожего на временный индекс или временный индекс.

0 голосов
/ 03 февраля 2013

Я бы порекомендовал создать метакласс и ORM. Из метакласса init вызовите метод init_schema для инициализации счетчиков, схемы, ключей и т. Д. Таким образом вы не будете вызывать sure_index при каждом обновлении запроса или коллекции:)

...