2011-05-06 24 views
46

No entiendo la diferencia entre create_index y ensure_index en pymongo. Por MongoDB indexes page, se dicePymongo/MongoDB: crear índice o asegurar el índice?

puede crear un índice llamando al ensureIndex()

Sin embargo, en pymongo hay dos comandos diferentes create_index y ensure_index, y la documentación para crear el índice tiene:

A diferencia de create_index(), que intenta crear un índice incondicionalmente, ensure_index() aprovecha el almacenamiento en caché de dentro del controlador, de modo que solo intenta crear índices que podrían no existir. Cuando se crea (o asegura) un índice por PyMongo, se "recuerda" durante ttl segundos. Las llamadas repetidas a ensure_index() dentro de ese límite de tiempo serán livianas: no intentarán crear realmente el índice.

Estoy en lo cierto al entender que ensure_index creará un índice permanente, o tengo que usar create_index para esto?

+0

En mongo 3.x ensureIndex está ** [en desuso] (http://stackoverflow.com/a/30314946/1090562) ** y, por lo tanto, es mejor dejar de usarlo. Incluso si todavía está en la versión 2.6, es mejor estar preparado de antemano y asegurarse de que haya menos sorpresas en la futura migración. –

Respuesta

13

Tenga en cuenta que en Mongo 3.x ensureIndex es obsoleto y debe ser desalentado

Obsoleto desde la versión 3.0.0: db.collection.ensureIndex() ahora es un alias de db.collection.createIndex().

El mismo se encuentra en pymongo:

DEPRECATED - Se asegura de que existe un índice en esta colección.

Lo que significa que siempre debe usar create_index.

3

Todos los índices son permanentes. ensure_index() es solo un pequeño contenedor alrededor de create_index().

"" " La función ensureIndex() sólo crea el índice si no existe. ''"

hay nada como un índice transitorio o un índice temporal.

+1

Creo que esto no es del todo correcto. Llamar a 'ensureIndex()' desde el shell de mongodb solo creará un índice si no existe. Sin embargo, por lo que puedo decir, al llamar al método 'ensure_index()' desde la interfaz de python se creará un índice * o se reconstruirá * si no se creó * recientemente *. –

38

@ Andreas-Jung es justo en que ensure_index() es un envoltorio sobre create_index(), creo que la confusión surge con la frase:

Cuando se crea un índice (o esté asegurada) por PyMongo se “recordado "Para ttl segundos.

No es que el índice es temporal o "transitoria", lo que sucede es que durante la cantidad de segundos, una llamada a ensure_index() tratando de crear el mismo índice de nuevo, se no tener ningún efecto y la voluntad no llame al create_index() debajo, pero después de que cache "expira", una llamada a ensure_index() llamará nuevamente create_index() debajo.

entiendo perfectamente su confusión porque francamente docs PyMongo no hacen un muy buen trabajo en explicar cómo funciona esto, pero si se dirige hacia el Ruby docs, la explicación es un poco más claro:

  • (String) ensure_index (spec, opta = {})

Pide create_index y establece un indicador para no hacerlo de nuevo por otros X minutos. este tiempo se puede especificar como una opción cuando se inicializa un objeto Mongo :: DB como opciones: [] Cualquier cache_time cambios en un índice se propagó a través independientemente del tiempo de caché (por ejemplo, un cambio de dirección de índice)

Los parámetros y opciones para este son los mismos que para Colección # create_index.

Ejemplos:

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

No estoy diciendo que los conductores funcionen exactamente igual, es solo que, con fines ilustrativos, su explicación es un poco mejor en mi humilde opinión.

9

El método ensureIndex en el Shell interactivo y ensure_index en el controlador python son cosas diferentes, aunque se usa la misma palabra. Tanto el método create_index como el ensure_index del controlador python crean un índice permanentemente.

Tal vez uno usaría ensure_index con un TTL razonable en tal situación, porque no estoy seguro si create_index recrearía el índice cada vez que lo llame. La recreación normalmente no es deseada y podría ser una operación pesada. Pero incluso ensure_index (del controlador python o también ruby) podría recrear el índice siempre que el TTL haya expirado o cuando lo llame desde una instancia de cliente diferente o después de un reinicio. No estoy seguro de esto.

Quizás una posibilidad incluso mejor es verificar primero, utilizando el método index_information(), si el índice ya existe. Si ya existe, no lo crearías de nuevo.

ahora estoy demostrando cómo el término se utiliza ensure_index (o ensureIndex) con 2 significados diferentes:

1) Se crea un índice si todavía no existe en la base de datos

Este es lo que el método intérprete interactivo ensureIndex() hace:

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

También el Node.JS MongoDB Driver se comporta de esta manera: (. Búsqueda de function ensureIndex en el archivo collection.js)

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

2) Se crea un índice si no es en el 'caché conductor

El mismo identificador se utiliza con un significado diferente aquí, que me parece confuso.

El controlador python y el controlador ruby ​​almacenan información en la memoria sobre los índices que se crearon recientemente, y llaman a este comportamiento 'caché'.

No informan a la base de datos sobre este almacenamiento en caché.

El resultado de este mecanismo es, si se llama a create_index o ensure_index por primera vez con un valor TTL (tiempo de vida), entonces el controlador insertará el índice en la base de datos y recordará esta inserción y también almacenar el Información TTL en la memoria. Lo que se almacena en caché aquí es la hora y el índice que fue.

La próxima vez que llame al ensure_index con el mismo índice de la misma colección en la misma instancia del controlador, el comando ensure_index solo volverá a insertar el índice si los segundos TTL no han transcurrido desde la primera llamada.

Si llama al create_index, el índice siempre se insertará, sin importar cuánto tiempo pasó desde la primera llamada, y por supuesto también si esta es la primera llamada.

Este es el controlador pitón, buscar def ensure_index en el archivo collection.py:

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

Y el conductor rubí, buscar def ensure_index en el archivo collection.rb:

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

(Tenga en cuenta que las diferentes instancias de cliente no saben sobre el almacenamiento en caché de los demás, esta información se mantiene en la memoria solo y es por instancia. Si reinicia la aplicación cliente, la nueva instancia desconoce las antiguas inserciones de índice "en caché". También otros clientes no saben, no se dicen entre sí.)

Todavía no podía entender por completo, lo que sucede en el DB, cuando el controlador de python o el controlador de ruby ​​insertan un índice que ya está allí.Sospecho que no hacen nada en este caso, lo que tiene más sentido y también coincide con el comportamiento del Interactive Shell y el controlador JS.

0

Recomendaría crear metaclass y ORM. De metaclase init método llamado init_schema para inicializar los contadores, esquemas, etc. teclas ello se evitan llamar ensure_index cada consulta o actualización de la colección :)