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 каждый запрос или обновление коллекции:)