2013-08-22 5 views
3

J'ai une collection dans MongoDB qui a les documents suivants.MongoDB n'utilise pas l'index composé sur '_id'

/* 0 */ 
{ 
    "T" : [ 
     374135056604448742 
    ], 
    "_id" : { 
     "#" : 7778532275691, 
     "ts" : ISODate("2013-07-26T02:25:00Z") 
    } 
} 

/* 1 */ 
{ 
    "T" : [ 
     1056188940167152853 
    ], 
    "_id" : { 
     "#" : 34103385525388, 
     "ts" : ISODate("2013-07-30T03:00:00Z") 
    } 
} 

/* 2 */ 
{ 
    "T" : [ 
     1056188940167152853 
    ], 
    "_id" : { 
     "#" : 34103385525388, 
     "ts" : ISODate("2013-07-30T03:18:00Z") 
    } 
} 

Maintenant, j'essaie d'interroger certains documents avec la requête suivante.

db.entries.find({ 
    '_id.ts': {'$gte': beginTS, '$lte': endTS}, 
    '_id.#' : 884327843395156951 
    }).hint([('_id', 1)]).explain() 

Selon ma compréhension, étant donné que _id est un champ composé, et maintient toujours un Mongo index sur _id, par conséquent répondre ci-dessus requête, Mongo aurait utilisé l'index sur « _id ». Cependant, la réponse à la requête ci-dessus est la suivante:

{u'allPlans': [{u'cursor': u'BtreeCursor _id_', 
    u'indexBounds': {u'_id': [[{u'$minElement': 1}, {u'$maxElement': 1}]]}, 
    u'n': 2803, 
    u'nscanned': 4869528, 
    u'nscannedObjects': 4869528}], 
u'cursor': u'BtreeCursor _id_', 
u'indexBounds': {u'_id': [[{u'$minElement': 1}, {u'$maxElement': 1}]]}, 
u'indexOnly': False, 
u'isMultiKey': False, 
u'millis': 128415, 
u'n': 2803, 
u'nChunkSkips': 0, 
u'nYields': 132, 
u'nscanned': 4869528, 
u'nscannedAllPlans': 4869528, 
u'nscannedObjects': 4869528, 
u'nscannedObjectsAllPlans': 4869528, 
u'scanAndOrder': False, 

Comme on peut l'observer, MongoDB fait une analyse complète de DB pour trouver juste quelques documents. Je ne sais pas ce qui ne va pas ici.

J'ai essayé de changer l'ordre de la requête, mais le même résultat. Je n'ai aucune idée de ce qui se passe ici. Toute aide si profondément appréciée.

MISE À JOUR

Je compris la nuance ici. Le _id n'est pas un index composé, c'est un simple indice exact. Cela signifie que si _id est un document, quelle que soit la structure du document et le nombre d'attr ou de sous-documents imbriqués qu'il peut contenir, l'index _id ne contiendra qu'une entrée pour le champ _id. Cette entrée est supposée être un hash de _id document et sera maintenue unique.

+0

Qu'est-ce que vous obtenez si vous exécutez db.entries.getIndexes()? – Mason

+0

Vous ne comprenez pas comment un '_id' est indexé. Voir cette question: http://stackoverflow.com/questions/7246434/expected-behaviour-of-compound-id-in-mongodb – WiredPrairie

Répondre

3

Vous utilisez un objet en tant que clé, mais vous êtes et non en utilisant un compund index ici.

L'index _id est un peu spécial, car il est créé automatiquement et est toujours unique. Normalement, l'index _id est un ObjectId, un UUID ou peut-être un integer ou une chaîne contenant une sorte de hachage. MongoDB prend en charge les objets complexes en tant que clés. Cependant, pour MongoDB, ce n'est encore qu'un document. Il peut être comparé à d'autres documents et les documents ayant les mêmes champs et valeurs seront égaux. Mais puisque vous n'avez pas créé les clés d'index (et vous ne pouvez pas créer cet index manuellement), MongoDB n'a aucune idée qu'il contient un champ # et un champ ts. Un index composé, d'autre part, fait référence aux champs d'un document de façon explicite, par ex. {"product.quantity" : 1, "product.created" : -1}. Cela doit être spécifié lors de la création de l'index.

Il semble que vous essayez de stocker essentiellement un horodatage dans votre clé primaire. Le ObjectId de MongoDB contient déjà un horodatage, de sorte que vous pouvez directement effectuer des requêtes de plage basées sur la date sur ObjectIds.

Questions connexes