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 plot campo de la movies colección:
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 cuenta la cantidad de documentos en la colección movies e incluye una sugerencia que especifica ese índice disperso, la operación devuelve solo los documentos que contienen el campo rated.
db.movies.countDocuments( {}, { hint: { rated: 1 } } )
Para obtener el recuento correcto de la cantidad de documentos en la movies colección, no utilice 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 consulta 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 consulta 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 password en el campo users en:
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" } )