Pymongo / MongoDB: создать индекс или обеспечить индекс?

Я не понимаю разницы между create_index и ensure_index в pymongo. На страница индексов MongoDB, он скажет

вы можете создать индекс по телефону ensureIndex()

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

в отличие от create_index(), который пытается создание индекса безусловно, ensure_index () использует некоторые кэширование в драйвере так, чтобы оно только попытки создать индексы, которые возможно, еще не существует. Когда индекс создается (или обеспечивается) PyMongo it "запоминается" на ttl секунды. Неоднократные призывы к ensure_index() в течение этого срока легкий вес - они не будут пытаться фактически создайте индекс.

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

5 ответов


имейте в виду, что в Mongo 3.x ensureIndex устарел и должен быть обескуражен.

устарел с версии 3.0.0: db.коллекция.ensureIndex () теперь является псевдонимом для db.коллекция.функции createindex().

то же самое pymongo:

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

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


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

при создании индекса (или обеспечить) по PyMongo это "помнят" для ttl считанные секунды.

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

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

  • (строка) ensure_index (spec, opts = {})

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

параметры и параметры для этого методы те же Коллекция#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

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


на ensureIndex метод в интерактивной оболочке и ensure_index в драйвере python есть разные вещи, хотя используется одно и то же слово. Оба create_index и ensure_index метод из драйвера python создает индекс постоянно.

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

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

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

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

это Интерактивная Оболочка метод 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) он создает индекс, если он не находится в "кэше драйверов"

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

python и драйвер 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

(обратите внимание, что различные экземпляры клиента не знают о кэшировании других, эта информация хранится только в памяти, и это на экземпляр. При перезапуске клиентского приложения новый экземпляр не знает о вставках старого "кэшированного" индекса. И другие клиенты не знают, они не говорят друг другу.)

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


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

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

нет ничего подобного переходному индексу или временному индексу.


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