Pymongo/MongoDB: создать индекс или обеспечить индекс? - программирование
Подтвердить что ты не робот

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

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

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

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

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

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

4b9b3361

Ответ 1

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

Устаревший с версии 3.0.0: db.collection.ensureIndex() теперь является псевдонимом для db.collection.createIndex().

То же самое происходит в pymongo:

DEPRECATED - Обеспечивает наличие индекса в этой коллекции.

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

Ответ 2

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

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

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

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

  • (String) secure_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

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

Ответ 3

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

Возможно, в такой ситуации можно использовать ensure_index с разумным TTL, потому что я не уверен, что create_index будет воссоздавать индекс каждый раз, когда вы его вызываете. Обычно отдых нежелателен, и это может быть тяжелая операция. Но даже ensure_index (питона или рубинового драйвера) возможно воссоздает индекс всякий раз, когда истекает срок действия 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

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

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

Ответ 4

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

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

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

Ответ 5

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