2012-03-06 16 views
20

Estoy implementando una base de datos de contactos que maneja bastantes campos. La mayoría de ellos están predefinidos y pueden considerarse vinculados, pero hay algunos que no lo están. Llamaremos a uno de estos campos 'grupos'. La forma en que actualmente ponemos en práctica es (cada documento/contacto tiene campo 'grupos'):Indexación de Mongo en arreglos de objetos frente a objetos

'groups' : { 
    152 : 'hi', 
    111 : 'group2' 
} 

pero después de un poco de lectura que he parecería que debería hacer es:

'groups' : [ 
    { 'id' : 152, 'name' : 'hi' }, 
    { 'id' : 111, 'name' : 'group2' } 
    ... 
] 

y luego aplique el índice db.contact.ensureIndex({'groups.id':1});

Mi pregunta es con respecto a la funcionalidad. ¿Cuáles son las diferencias entre las 2 estructuras y cómo se construye realmente el índice (es simplemente una indexación dentro de cada documento/contacto o está construyendo un índice de escala completa que tiene todos los grupos de todos los documentos/contactos?).

Estoy como bajo la suposición de que estructuralmente es la mejor manera, pero si soy incorrecto, házmelo saber.

Respuesta

35

Las consultas serán ciertamente mucho más sencillas en el segundo caso, donde 'grupos' es una matriz de subdocumentos, cada uno con 'id' y 'nombre'.

Mongo no admite consultas "comodín", por lo que si sus documentos se estructuraron de la primera manera y usted quería encontrar un subdocumento con el valor "hola", pero no sabía que la clave era 152, lo haría no ser capaz de hacerlo Con la segunda estructura de documento, puede consultar fácilmente para {"groups.name": "hola"}.

Para obtener más información sobre la consulta de objetos incrustados, consulte la documentación titulada "Punto de notación (estiramiento en objetos)" http://www.mongodb.org/display/DOCS/Dot+Notation+%28Reaching+into+Objects%29 El "valor en una matriz" y "valor en un objeto incrustado" secciones de las "Búsquedas avanzadas" la documentación también es útil: http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-ValueinanArray

Para un índice en {'groups.id': 1}, se creará una entrada de índice para cada tecla "id" en cada matriz de "grupos" en cada documento. Con un índice en "grupos", solo se creará una entrada de índice por documento.

Si tiene documentos del segundo tipo y un índice sobre grupos, sus consultas tendrán que coincidir con sub documentos completos para hacer uso del índice. Por ejemplo, dado el documento:

{ "_id" : 1, "groups" : [ { "id" : 152, "name" : "hi" }, { "id" : 111, "name" : "group2" } ] } 

La consulta

db.<collectionName>.find({groups:{ "id" : 152, "name" : "hi" }}) 

hará uso del índice, pero las consultas

db.<collectionName>.find({"groups":{$elemMatch:{name:"hi"}}}) 

o

db.<collectionName>.find({"groups.name":"hi"}) 

no lo hará .

Los índices que crea deben depender de las consultas que normalmente realizará.

Puede experimentar con los índices (si corresponde) que utilizan las consultas con el comando .explain(). http://www.mongodb.org/display/DOCS/Explain La primera línea, "cursor" le dirá qué índice se está utilizando. "cursor": "BasicCursor" indica que se está realizando un escaneo completo de la colección.

Hay más información sobre la indexación en la documentación: http://www.mongodb.org/display/DOCS/Indexes

La sección "Indexación elementos de un array" enlace de arriba en el documento titulado "Multikeys": http://www.mongodb.org/display/DOCS/Multikeys

Esperamos que esto mejorará su comprensión de cómo consultar documentos incrustados y cómo se usan los índices. Por favor, háganos saber si tiene alguna pregunta de seguimiento.

+0

Esta es una gran respuesta, pero los primeros dos enlaces están rotos. He estado buscando y no puedo encontrar su nueva ubicación en la red. ¿Alguna ayuda? – portforwardpodcast

+0

Hola, al leer su respuesta, me preguntaba si el índice se usará para consultas como 'db. .find ({" groups ": {$ elemMatch: {" id ": 152}}})' –

Cuestiones relacionadas