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, utiliza la db.collection.createIndex() método con la opción sparse configurada a true.
Por ejemplo, la siguiente operación en mongosh crea un índice disperso en el campo plot de la colección movies:
db.movies.createIndex( { "plot": 1 }, { sparse: true } )
El índice no indexa documentos que no incluyen el campo plot.
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 { plot: { $exists: false } } no utilizará un índice disperso en el campo plot 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.
Por ejemplo, cree un índice disperso en el campo rated de la colección movies.
db.movies.createIndex( { rated: 1 }, { sparse: true } )
Si cuentas el número de documentos en la colección movies e incluyes una sugerencia que especifique ese índice disperso, la operación devuelve únicamente los documentos que contienen el campo rated.
db.movies.countDocuments( {}, { hint: { rated: 1 } } )
Para obtener el recuento correcto del número de documentos en la colección movies, no hint() con un índice disperso al realizar un recuento de todos los documentos en una colección.
db.movies.countDocuments()
Í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 |
Propiedades dispersas y únicas
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
El siguiente ejemplo crea un índice disperso en el campo password:
db.users.createIndex( { password: 1 } , { sparse: true } )
Luego, la siguiente query en la colección users utiliza el índice disperso para devolver los documentos que tienen el campo password:
db.users.find( { password: { $exists: true } } ).sort({ password: 1 }).limit(5)
Si un usuario no contiene el campo password, la query no devuelve ese usuario.
Un índice disperso en una colección no puede devolver resultados completos
Considere la colección movies donde algunos documentos no tienen un campo plot.
El siguiente ejemplo crea un índice disperso en el campo plot:
db.movies.createIndex( { "plot": 1 }, { sparse: true } )
Considera el siguiente query para devolver todos los documentos de la colección movies, ordenados por el campo plot:
db.movies.find().sort( { plot: -1 } )
Aunque la clasificación se realiza por campo indexado, si algunos documentos en la movies colección no tienen un plot campo, MongoDB no selecciona el índice disperso para completar la consulta con el fin de devolver resultados completos.
Para usar el índice disperso, especifica explícitamente el índice con hint():
db.movies.find().sort( { plot: -1 } ).hint( { plot: 1 } ).limit(5)
Esta consulta solo devuelve documentos en la colección movies que contienen el campo plot.
Índice disperso con restricción de unicidad
La siguiente operación crea un índice con una restricción única y un filtro disperso en el campo password en el users:
db.users.createIndex( { password: 1 } , { sparse: true, unique: true } )
Este índice permitiría la inserción de documentos que tuvieran valores únicos para el campo password o que no incluyeran un campo password. Así, dados los documentos existentes en la colección users, el índice permite las siguientes operaciones de inserción:
db.users.insertMany( [ { "name": "Jon Snow", "email": "jon@gameofthron.es", "password": "$2b$12$newHashedPassword1234567890ABC" }, { "name": "Sansa Stark", "email": "sansa@gameofthron.es", "password": "$2b$12$anotherNewPassword1234567890DEF" }, { "name": "Bran Stark", "email": "bran@gameofthron.es" } ] )
Sin embargo, el índice no permitiría la adición de documentos que contengan direcciones de correo electrónico que ya existen en la colección.
Í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.users.createIndex( { password : 1 }, { name: "unique_index", unique: true } )
db.users.createIndex( { password : 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.users.createIndex( { password : 1 }, { name: "sparse_index", sparse: true } )
db.users.createIndex( { password : 1 }, { name: "basic_index" } )