Menu Docs

Página inicial do DocsDesenvolver aplicaçõesManual do MongoDB

Índices esparsos

Nesta página

  • Crie um índice esparso
  • Comportamento
  • Exemplos

Í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

O MongoDB fornece a opção de criar índices parciais. Os índices parciais oferecem um superconjunto da funcionalidade de índices escassos. Deve-se preferir índices parciais em relação a índices esparsos.

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 em mongosh cria um índice escasso no campo xmpp_id da collection addresses :

db.addresses.createIndex( { "xmpp_id": 1 }, { sparse: true } )

O índice não indexa documentos que não incluem o campo xmpp_id.

Observação

Não confunda índices esparsos no MongoDB com nível de bloco índices em outros bancos de dados. Pense neles como índices densos com um filtro específico.

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 { x: { $exists: false } } não usará um índice esparso no campo x , a menos que seja explicitamente sugerido. Para ver um exemplo que detalha o comportamento, consulte Um índice esparso em uma collection não retorna resultados completos .

Se você incluir um hint() que especifica um índice esparso ao executar um count() de todos os documentos em uma collection (ou seja, com um predicado de query vazio), o índice esparso será usado mesmo que resulte em uma contagem incorreta.

db.collection.insertOne( { _id: 1, y: 1 } );
db.collection.createIndex( { x: 1 }, { sparse: true } );
db.collection.find().hint( { x: 1 } ).count();

Para obter a contagem correta, não hint() com um índice esparso ao executar uma contagem de todos os documentos em uma collection.

db.collection.find().count();
db.collection.createIndex( { y: 1 } );
db.collection.find().hint( { y: 1 } ).count();

Os seguintes tipos de índice são sempre escassos:

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
Índices crescentes
Índices decrescentes
Somente indexa documentos que contêm um valor para pelo menos uma das chaves.
Índices crescentes
Índices decrescentes
Indexa um documento somente quando ele contém um valor para um dos campos geospatial. Não indexa documentos nos índices crescentes ou decrescentes.
Índices crescentes
Índices decrescentes
Somente indexa um documento quando ele corresponde a um dos campostext. Não indexa documentos nos índices crescentes ou decrescentes.

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.

Considere uma collection scores que contenha os seguintes documentos:

{ "_id" : ObjectId("523b6e32fb408eea0eec2647"), "userid" : "newbie" }
{ "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 }
{ "_id" : ObjectId("523b6e6ffb408eea0eec2649"), "userid" : "nina", "score" : 90 }

A collection tem um índice esparso no campo score:

db.scores.createIndex( { score: 1 } , { sparse: true } )

Em seguida, a seguinte query na collection scores usa o índice esparso para retornar os documentos que têm o campo score menor que($lt) 90:

db.scores.find( { score: { $lt: 90 } } )

Como o documento para o userid"newbie" não contém o campo score e, portanto, não atende aos critérios da query, esta pode usar o índice esparso para retornar os resultados:

{ "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 }

Considere uma collection scores que contenha os seguintes documentos:

{ "_id" : ObjectId("523b6e32fb408eea0eec2647"), "userid" : "newbie" }
{ "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 }
{ "_id" : ObjectId("523b6e6ffb408eea0eec2649"), "userid" : "nina", "score" : 90 }

A collection tem um índice esparso no campo score:

db.scores.createIndex( { score: 1 } , { sparse: true } )

Como o documento para o userid "newbie" não contém o campo score, o índice esparso não contém uma entrada para esse documento.

Considere a seguinte query para retornar todos os documentos da collection scores, classificados pelo campo score:

db.scores.find().sort( { score: -1 } )

Mesmo que a classificação seja pelo campo indexado, o MongoDB não selecionará o índice esparso para atender à query a fim de retornar resultados completos:

{ "_id" : ObjectId("523b6e6ffb408eea0eec2649"), "userid" : "nina", "score" : 90 }
{ "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 }
{ "_id" : ObjectId("523b6e32fb408eea0eec2647"), "userid" : "newbie" }

Para utilizar o índice esparso, especifique explicitamente o índice com hint():

db.scores.find().sort( { score: -1 } ).hint( { score: 1 } )

O uso do índice resulta na devolução somente dos documentos com o campo score:

{ "_id" : ObjectId("523b6e6ffb408eea0eec2649"), "userid" : "nina", "score" : 90 }
{ "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 }

Dica

Veja também:

Considere uma collection scores que contenha os seguintes documentos:

{ "_id" : ObjectId("523b6e32fb408eea0eec2647"), "userid" : "newbie" }
{ "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 }
{ "_id" : ObjectId("523b6e6ffb408eea0eec2649"), "userid" : "nina", "score" : 90 }

Você pode criar um índice com uma restrição única e filtro esparso no campo score utilizando a seguinte operação:

db.scores.createIndex( { score: 1 } , { sparse: true, unique: true } )

Esse índice permitiria a inserção de documentos que tivessem valores exclusivos para o campo score ou que não incluíssem um campo score. Dessa forma, considerando-se os documentos existentes na collection scores, o índice permite as seguintes operações de inserção:

db.scores.insertMany( [
{ "userid": "newbie", "score": 43 },
{ "userid": "abby", "score": 34 },
{ "userid": "nina" }
] )

No entanto, o índice não permitiria a adição dos seguintes documentos, pois já existem documentos com valor score de 82 e 90:

db.scores.insertMany( [
{ "userid": "newbie", "score": 82 },
{ "userid": "abby", "score": 90 }
] )

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 collection.

Este exemplo cria vários índices com o mesmo padrão de chave e diferentes opções sparse:

db.scoreHistory.createIndex( { score : 1 }, { name: "unique_index", unique: true } )
db.scoreHistory.createIndex( { score : 1 }, { name: "unique_sparse_index", unique: true, sparse: true } )

Você também pode criar índices básicos com o mesmo padrão de chave com e sem a opção esparsa:

db.scoreHistory.createIndex( { score : 1 }, { name: "sparse_index", sparse: true } )
db.scoreHistory.createIndex( { score : 1 }, { name: "basic_index" } )
← Índices ocultos