web-dev-qa-db-fra.com

Pymongo / MongoDB: créer un index ou assurer l'index?

Je ne comprends pas la différence entre create_index Et ensure_index Dans pymongo. Sur la page d'index MongoDB , il est dit

vous pouvez créer un index en appelant la ensureIndex()

Cependant, dans pymongo, il existe deux commandes différentes create_index et ensure_index , et la documentation de create index contient:

Contrairement à create_index (), qui tente de créer un index sans condition, assure_index () tire parti de la mise en cache dans le pilote de telle sorte qu'il tente uniquement de créer des index qui n'existent peut-être pas déjà. Lorsqu'un index est créé (ou assuré) par PyMongo, il est "mémorisé" pendant ttl secondes. Les appels répétés à assure_index () dans ce délai seront légers - ils n'essaieront pas de créer réellement l'index.

Ai-je raison de comprendre que ensure_index Va créer un index permanent, ou dois-je utiliser create_index Pour cela?

48
YXD

Gardez à l'esprit que dans Mongo 3.x assureIndex est déconseillé et doit être déconseillé.

Déconseillé depuis la version 3.0.0: db.collection.ensureIndex () est désormais un alias pour db.collection.createIndex ().

La même chose est dans pymongo :

DEPRECATED - Garantit qu'un index existe sur cette collection.

Ce qui signifie que vous devez toujours utiliser create_index.

14
Salvador Dali

@ andreas-jung a raison en ce que ensure_index() est un wrapper sur create_index(), je pense que la confusion survient avec la phrase:

Lorsqu'un index est créé (ou assuré) par PyMongo, il est "mémorisé" pendant ttl secondes.

Ce n'est pas que l'index soit temporaire ou "transitoire", ce qui se passe c'est que pendant le nombre de secondes spécifié, un appel à ensure_index() essayant de recréer le même index sera pas avoir un effet et pas appeler create_index() en dessous, mais après ce "cache" expire, un appel à ensure_index() appellera à nouveau create_index() en dessous.

Je comprends parfaitement votre confusion car très franchement les documents de PyMongo ne font pas un très bon travail pour expliquer comment cela fonctionne, mais si vous vous dirigez vers les Ruby docs , l'explication est un peu plus claire:

  • (Chaîne) sure_index (spec, opts = {})

Appelle create_index et définit un indicateur pour ne plus recommencer pendant X minutes supplémentaires. cette heure peut être spécifiée comme option lors de l'initialisation d'un objet Mongo :: DB en tant qu'options [: cache_time] Toutes les modifications apportées à un index seront propagées indépendamment de l'heure de la mémoire cache (par exemple, un changement de direction de l'index)

Les paramètres et options de ces méthodes sont les mêmes que ceux de la collection # create_index.

Exemples:

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

Je ne prétends pas que les pilotes fonctionnent exactement de la même manière, c'est juste qu'à des fins d'illustration, leur explication est un peu meilleure à mon humble avis.

39
Juan Gomez

La méthode ensureIndex dans le shell interactif et ensure_index Dans le pilote python sont des choses différentes, bien que le même mot soit utilisé. Les deux create_index et la méthode ensure_index du pilote python crée un index de façon permanente.

Peut-être que l'on utiliserait ensure_index Avec un TTL dans une telle situation raisonnable, car je ne sais pas si create_index Recréerait l'index chaque fois que vous l'appelez. Les loisirs ne sont normalement pas souhaités et cela pourrait être une opération lourde. Mais même ensure_index (Du python ou aussi Ruby driver) pourrait éventuellement recréer l'index chaque fois que le TTL est expiré ou lorsque vous l'appelez à partir d'une autre instance client ou après un redémarrage. Je ne suis pas sûr de cela.

Peut-être une possibilité encore meilleure est de vérifier d'abord, en utilisant la méthode index_information(), si l'index existe déjà. S'il existe déjà, vous ne le créeriez pas à nouveau.

Je montre maintenant comment le terme ensure_index (Ou ensureIndex) est utilisé avec 2 significations différentes:

1) Il crée un index s'il n'existe pas encore dans la base de données

C'est ce que fait la méthode Interactive ShellensureIndex():

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

Le Node.JS MongoDB Driver Se comporte également de cette façon:

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

(Recherchez function ensureIndex Dans le fichier collection.js.)

2) Il crée un index s'il n'est pas dans le 'cache du pilote'

Le même identifiant est utilisé avec une signification différente ici, ce que je trouve confus.

Le pilote python et Ruby stockent des informations en mémoire sur les index qui ont été créés récemment, et ils appellent ce comportement "mise en cache").

Ils n'informent pas la base de données de cette mise en cache.

Le résultat de ce mécanisme est que si vous appelez create_index Ou ensure_index Pour la première fois avec une valeur TTL (durée de vie), le pilote insérez l'index dans la base de données et se souviendra de cette insertion et stockera également les informations TTL en mémoire. Ce qui est mis en cache ici, c'est l'heure et quel index il s'agissait.

La prochaine fois que vous appellerez ensure_index Avec le même index de la même collection sur la même instance de pilote, la commande ensure_index N'insérera à nouveau l'index que si TTL = les secondes ne se sont pas encore écoulées depuis le premier appel.

Si vous appelez create_index, L'index sera toujours inséré, quel que soit le temps écoulé depuis le premier appel, et bien sûr aussi s'il s'agit du premier appel.

Voici le pilote python, recherchez def ensure_index Dans le fichier collection.py:

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

Et le pilote Ruby, recherchez def ensure_index Dans le fichier collection.rb:

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

(Notez que différentes instances clientes ne connaissent pas la mise en cache des autres, ces informations sont conservées en mémoire uniquement et elles le sont par instance. Si vous redémarrez l'application cliente, la nouvelle instance ne connaît pas les anciennes insertions d'index 'mises en cache'. Les autres clients ne se connaissent pas non plus, ils ne se disent pas.)

Je n’étais pas encore en mesure de comprendre pleinement ce qui se passe dans la base de données, lorsque le pilote python ou le pilote Ruby insère un index qui est déjà là. Je soupçonneraient qu'ils ne font rien dans ce cas, ce qui est plus logique et correspondrait également au comportement de Interactive Shell et du pilote JS.

9
mit

Tous les index sont permanents. assure_index () est juste un petit wrapper autour de create_index ().

"" "La fonction assureIndex () crée uniquement l'index s'il n'existe pas." ""

Il n'y a rien de tel qu'un index transitoire ou un index temporaire.

3
Andreas Jung