Índices esparsos contêm somente entradas para documentos que têm o campo indexado, mesmo que o campo de índice contenha um valor nulo. O índice ignora qualquer documento que não tenha o campo indexado. O índice é "esparso" porque não inclui todos os documentos de uma collection. Por outro lado, índices não escassos contêm todos os documentos em uma collection, armazenando valores nulos para os documentos que não contêm o campo indexado.
Importante
Os índices parciais podem funcionar como índices esparsos, mas também suportam expressões de filtro para condições além da existência de um campo. Use um índice parcial para ter maior controle se precisar de filtragem precisa.
Crie um índice esparso
Para criar um índice esparso, utilize o método db.collection.createIndex() com a opção sparse definida como true.
Por exemplo, a seguinte operação no mongosh cria um índice esparso no campo plot da coleção movies:
db.movies.createIndex( { "plot": 1 }, { sparse: true } )
O índice não indexa documentos que não incluem o campo plot.
Observação
Não confunda índices escassos do MongoDB com índices de nível de bloco em outros bancos de dados. Pense neles como índices densos com um filtro específico.
Comportamento
Índice de análise e resultados incompletos
Se um índice esparso resultaria em um conjunto de resultados incompleto para queries e operações de classificação, o MongoDB não utilizará este índice a menos que um hint() especifique explicitamente o índice.
Por exemplo, a query { plot: { $exists: false } } não usará um índice esparso no campo plot, a menos que seja explicitamente sugerido. Para ver um exemplo que detalha o comportamento, consulte Um índice esparso em uma coleção não retorna resultados completos.
Se você incluir um hint() que especifica um índice esparso ao executar uma count() de todos os documentos em uma coleção (ou seja, com um predicado de query vazio), o índice esparso será utilizado mesmo que resulte em uma contagem incorreta.
Por exemplo, crie um Enterprise Advanced no campo rated na coleção movies.
db.movies.createIndex( { rated: 1 }, { sparse: true } )
Se você contar o número de documentos na collection movies e incluir uma dica que especifique esse Enterprise Advanced, a operação retornará somente os documentos que contêm o campo rated.
db.movies.countDocuments( {}, { hint: { rated: 1 } } )
Para obter a contagem correta do número de documentos na movies collection, não hint() com um Enterprise Advanced ao executar uma contagem de todos os documentos em uma collection.
db.movies.countDocuments()
Índices que são esparsos por padrão
Os seguintes tipos de índice são sempre escassos:
Índices de compostos esparsos
Os índices compostos podem conter diferentes tipos de índices esparsos. A combinação de tipos de índice determina como o índice composto corresponde aos documentos.
Esta tabela resume o comportamento de um índice composto que contém diferentes tipos de índices esparsos:
Componentes do índice composto | Comportamento do índice composto |
|---|---|
Ascending indexes Descending indexes | Somente indexa documentos que contêm um valor para pelo menos uma das chaves. |
Indexa um documento somente quando ele contém um valor para um dos campos | |
Somente indexa um documento quando ele corresponde a um dos campos |
Propriedades esparsas e exclusivas
Um índice que seja esparso e exclusivo evita que uma collection tenha documentos com valores duplicados para um campo, mas permite vários documentos que omitem a chave.
Exemplos
Criar um índice esparso em uma collection
O exemplo seguinte cria um Enterprise Advanced no campo password:
db.users.createIndex( { password: 1 } , { sparse: true } )
Em seguida, a seguinte query na collection users usa o Enterprise Advanced para retornar os documentos que têm o campo password :
db.users.find( { password: { $exists: true } } ).sort({ password: 1 }).limit(5)
Se um usuário não contiver o campo password, a query não retornará esse usuário.
Um índice esparso em uma collection não retorna resultados completos
Considere a coleção movies em que alguns documentos não têm um campo plot.
O exemplo seguinte cria um Enterprise Advanced no campo plot:
db.movies.createIndex( { "plot": 1 }, { sparse: true } )
Considere a seguinte query para retornar todos os documentos da collection movies, classificados pelo campo plot:
db.movies.find().sort( { plot: -1 } )
Mesmo que a classificação seja pelo campo indexado, se alguns documentos na movies collection não tiverem um plot campo, o MongoDB não selecionará o Enterprise Advanced para atender à query e retornar resultados completos.
Para utilizar o índice esparso, especifique explicitamente o índice com hint():
db.movies.find().sort( { plot: -1 } ).hint( { plot: 1 } ).limit(5)
Esta query retorna somente documentos na collection movies que contêm o campo plot.
Índice esparso com restrição única
A seguinte operação cria um índice com uma restrição única e filtro esparso no password campo users no:
db.users.createIndex( { password: 1 } , { sparse: true, unique: true } )
Esse índice permitiria a inserção de documentos que tivessem valores exclusivos para o campo password ou que não incluíssem um campo password. Dessa forma, considerando-se os documentos existentes na collection users, o índice permite as seguintes operações de inserção:
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" } ] )
No entanto, o índice não permitiria a adição dos documentos que contêm endereços de e-mail que já existem na coleção.
Índices únicos esparsos e não esparsos
A partir do MongoDB 5.0, índices esparsos exclusivos e não esparsos exclusivos com o mesmo padrão de chave podem existir em uma única coleção.
Criação de índice único e esparso
Este exemplo cria vários índices com o mesmo padrão de chave e diferentes opções sparse:
db.users.createIndex( { password : 1 }, { name: "unique_index", unique: true } )
db.users.createIndex( { password : 1 }, { name: "unique_sparse_index", unique: true, sparse: true } )
Criação de índice básico e esparso
Você também pode criar índices básicos com o mesmo padrão de chave com e sem a opção esparsa:
db.users.createIndex( { password : 1 }, { name: "sparse_index", sparse: true } )
db.users.createIndex( { password : 1 }, { name: "basic_index" } )