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
для этого?
Ответы
Ответ 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 каждого обновления запроса или коллекции:)