Los índices dispersos solo contienen entradas para documentos que tienen el campo indexado, incluso si el campo indexado contiene un valor nulo. El índice omite cualquier documento que no tenga el campo indexado. El índice es "disperso" porque no incluye todos los documentos de una colección. Por el contrario, los índices que no son escasos contienen todos los documentos de una colección, y almacenan valores nulos para aquellos documentos que no contienen el campo indexado.
Importante
Los índices parciales pueden funcionar como índices dispersos, pero también admiten expresiones de filtro para condiciones más allá de si un campo existe. Utiliza un índice parcial para obtener un mayor control si necesitas un filtro exacto.
Crear un índice disperso
Para crear un índice disperso, utilice el db.collection.createIndex()Método con la sparse opción establecida true en.
Por ejemplo, la siguiente operación en mongosh crea un índice disperso en el campo xmpp_id de la colección addresses:
db.addresses.createIndex( { "xmpp_id": 1 }, { sparse: true } )
El índice no indexa documentos que no incluyen el campo xmpp_id.
Nota
No confunda los índices dispersos en MongoDB con los índices a nivel de bloque. Índices en otras bases de datos. Considérelos como índices densos con un filtro específico.
Comportamiento
Índice disperso y resultados incompletos
Si un índice disperso produce un conjunto de resultados incompleto para las operaciones de ordenación y quieries, MongoDB no utilizará ese índice a menos que un hint() lo especifique explícitamente.
Por ejemplo, el query { x: { $exists: false } } no utilizará un índice disperso en el campo x a menos que se indique explícitamente. Consulta El índice disperso en una colección no puede devolver resultados completos para un ejemplo que detalla el comportamiento.
Si incluye un hint() que especifica un índice disperso cuando realiza un count() de todos los documentos en una colección (es decir, con un predicado de query vacío), se utiliza el índice disperso incluso si da como resultado un conteo incorrecto.
db.collection.insertOne( { _id: 1, y: 1 } ); db.collection.createIndex( { x: 1 }, { sparse: true } ); db.collection.find().hint( { x: 1 } ).count();
Para obtener el conteo correcto, no hint() con un índice disperso al realizar un conteo de todos los documentos de una colección.
db.collection.find().count(); db.collection.createIndex( { y: 1 } ); db.collection.find().hint( { y: 1 } ).count();
Índices que son escasos por defecto
Los siguientes tipos de índices siempre son dispersos:
Índices compuestos dispersos
Los índices compuestos pueden contener diferentes tipos de índices dispersos. La combinación de tipos de índice determina cómo el índice compuesto coincide con los documentos.
Esta tabla resume el comportamiento de un índice compuesto que incluye diferentes tipos de índices escasos:
Componentes del índice compuesto | Comportamiento del índice compuesto |
|---|---|
Ascending indexes Descending indexes | Solo indexa documentos que contengan un valor para, al menos, una de las claves. |
Solo indexa un documento cuando este contiene un valor para uno de los campos | |
Solo indexa un documento cuando coincide con uno de los campos |
sparse y unique Propiedades
Un índice que es tanto disperso como único impide que una colección tenga documentos con valores duplicados para un campo, pero permite múltiples documentos que omiten la clave.
Ejemplos
Crea un índice disperso en una colección
Considere una colección scores que contiene los siguientes documentos:
{ "_id" : ObjectId("523b6e32fb408eea0eec2647"), "userid" : "newbie" } { "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 } { "_id" : ObjectId("523b6e6ffb408eea0eec2649"), "userid" : "nina", "score" : 90 }
La colección tiene un índice disperso en el campo score:
db.scores.createIndex( { score: 1 } , { sparse: true } )
A continuación, el siguiente query sobre la colección scores utiliza el índice disperso para devolver los documentos que tienen el campo score menor que ($lt) 90:
db.scores.find( { score: { $lt: 90 } } )
Debido a que el documento para el ID de usuario "newbie" no contiene el campo score y, por lo tanto, no cumple con los criterios de query, el query puede utilizar el índice disperso para devolver los resultados:
{ "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 }
Un índice disperso en una colección no puede devolver resultados completos
Considere una colección scores que contiene los siguientes documentos:
{ "_id" : ObjectId("523b6e32fb408eea0eec2647"), "userid" : "newbie" } { "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 } { "_id" : ObjectId("523b6e6ffb408eea0eec2649"), "userid" : "nina", "score" : 90 }
La colección tiene un índice disperso en el campo score:
db.scores.createIndex( { score: 1 } , { sparse: true } )
Debido a que el documento para el ID de usuario "newbie" no contiene el campo score, el índice disperso no contiene una entrada para ese documento.
Considera el siguiente query para devolver todos los documentos de la colección scores, ordenados por el campo score:
db.scores.find().sort( { score: -1 } )
Aunque la ordenación sea por el campo indexado, MongoDB no seleccionará el índice disperso para cumplir con el query y devolver resultados completos:
{ "_id" : ObjectId("523b6e6ffb408eea0eec2649"), "userid" : "nina", "score" : 90 } { "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 } { "_id" : ObjectId("523b6e32fb408eea0eec2647"), "userid" : "newbie" }
Para usar el índice disperso, especifica explícitamente el índice con hint():
db.scores.find().sort( { score: -1 } ).hint( { score: 1 } )
El uso del índice produce la devolución de solo aquellos documentos que tienen el campo score:
{ "_id" : ObjectId("523b6e6ffb408eea0eec2649"), "userid" : "nina", "score" : 90 } { "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 }
Índice disperso con restricción de unicidad
Considere una colección scores que contiene los siguientes documentos:
{ "_id" : ObjectId("523b6e32fb408eea0eec2647"), "userid" : "newbie" } { "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 } { "_id" : ObjectId("523b6e6ffb408eea0eec2649"), "userid" : "nina", "score" : 90 }
Podrías crear un índice con una restricción única y un filtro disperso en el campo score utilizando la siguiente operación:
db.scores.createIndex( { score: 1 } , { sparse: true, unique: true } )
Este índice permitiría la inserción de documentos que tuvieran valores únicos para el campo score o que no incluyeran un campo score. Así, dados los documentos existentes en la colección scores, el índice permite las siguientes operaciones de inserción:
db.scores.insertMany( [ { "userid": "newbie", "score": 43 }, { "userid": "abby", "score": 34 }, { "userid": "nina" } ] )
Sin embargo, el índice no permitiría la adición de los siguientes documentos ya que ya existen documentos con el valor score de 82 y 90:
db.scores.insertMany( [ { "userid": "newbie", "score": 82 }, { "userid": "abby", "score": 90 } ] )
Índices únicos escasos y no escasos
A partir de MongoDB 5.0, los índices dispersos únicos y los índices no dispersos únicos con el mismo patrón de clave pueden existir en una sola colección.
Creación de índices únicos y dispersos
Este ejemplo crea múltiples índices con el mismo patrón de clave y diferentes opciones de sparse:
db.scoreHistory.createIndex( { score : 1 }, { name: "unique_index", unique: true } ) db.scoreHistory.createIndex( { score : 1 }, { name: "unique_sparse_index", unique: true, sparse: true } )
Creación de índices básicos y dispersos
También se pueden crear índices básicos con el mismo patrón de claves con y sin la opción de dispersión:
db.scoreHistory.createIndex( { score : 1 }, { name: "sparse_index", sparse: true } ) db.scoreHistory.createIndex( { score : 1 }, { name: "basic_index" } )