Menu Docs
Página inicial do Docs
/
Manual do MongoDB
/ /

Índices Parciais

Nesta página

  • Criar um índice parcial
  • Comportamento
  • Restrições
  • Exemplos

Novo na versão 3.2.

Os índices parciais indexam apenas os documentos em uma collection que atendem a uma expressão de filtro especificada. Ao indexar um subconjunto de documentos em uma collection, os índices parciais têm requisitos de armazenamento mais baixos e custos de desempenho reduzidos para criação e manutenção de índices.

Para criar um índice partial, use o método db.collection.createIndex() com a opção partialFilterExpression. A opção partialFilterExpression aceita um documento que especifica a condição do filtro usando:

  • expressões de igualdade (ou seja, field: value ou usando o operador $eq),

  • $exists: true expressão,

  • $gt, $gte, $lt, $lte expressions,

  • $type expressões,

  • $and operador apenas no nível superior

Por exemplo, a seguinte operação cria um índice composto que indexa somente os documentos com um campo rating maior que 5.

db.restaurants.createIndex(
{ cuisine: 1, name: 1 },
{ partialFilterExpression: { rating: { $gt: 5 } } }
)

Você pode especificar uma opção partialFilterExpression para todos os tipos de índiceMongoDB.

O MongoDB não utiliza o índice parcial para uma query ou operação de classificação se utilizar os resultados do índice em um conjunto de resultados incompleto.

Para usar o índice parcial, uma query deve conter a expressão de filtro (ou uma expressão de filtro modificada que especifica um subconjunto da expressão de filtro) como parte de sua condição.

Por exemplo, considerando o índice a seguir:

db.restaurants.createIndex(
{ cuisine: 1 },
{ partialFilterExpression: { rating: { $gt: 5 } } }
)

A query a seguir pode usar o índice, pois seu predicado inclui a condição rating: { $gte: 8 } que corresponde a um subconjunto de documentos correspondentes à expressão de filtrorating: { $gt: 5 } do índice:

db.restaurants.find( { cuisine: "Italian", rating: { $gte: 8 } } )

No entanto, a query a seguir não pode usar o índice parcial no campo cuisine porque o uso do índice resulta em um conjunto de resultados incompleto. Especificamente, o predicado da query inclui a condição rating: { $lt: 8 }, enquanto o índice tem o filtro rating: { $gt: 5 }. Ou seja, a query { cuisine: "Italian", rating: { $lt: 8 } } corresponde a mais documentos (por exemplo, um restaurante italiano com uma classificação igual a 1) do que os indexados.

db.restaurants.find( { cuisine: "Italian", rating: { $lt: 8 } } )

Da mesma forma, a query a seguir não pode usar o índice parcial porque o predicado da query não inclui a expressão de filtro e o uso do índice retornaria um conjunto de resultados incompleto.

db.restaurants.find( { cuisine: "Italian" } )

Os índices parciais são preferidos em relação aos índices esparsos. Os índices parciais fornecem os seguintes benefícios:

  • Maior controle de quais documentos são indexados.

  • Um superconjunto da funcionalidade oferecida pelos índices esparsos.

Índices esparsos selecionam documentos para indexar somente com base na existência do campo indexado ou, para índices compostos, na existência dos campos indexados.

Os índices parciais determinam as entradas de índice com base no filtro especificado. O filtro pode incluir campos diferentes das chaves de índice e pode especificar condições diferentes de apenas uma verificação de existência. Por exemplo, um índice parcial pode implementar o mesmo comportamento de um índice esparso:

db.contacts.createIndex(
{ name: 1 },
{ partialFilterExpression: { name: { $exists: true } } }
)

Este índice parcial suporta as mesmas queries que um índice esparso no campo name.

No entanto, um índice parcial também pode especificar expressões de filtro em campos diferentes da chave de índice. Por exemplo, a seguinte operação cria um índice parcial, no qual o índice está no campo name, mas a expressão de filtro está no campo email :

db.contacts.createIndex(
{ name: 1 },
{ partialFilterExpression: { email: { $exists: true } } }
)

Para que o otimizador de queries escolha esse índice parcial, o predicado da query deve incluir uma condição no campo name, bem como uma correspondência não nula no campo email.

Por exemplo, a query a seguir pode usar o índice porque inclui uma condição no campo name e uma correspondência não nula no campo email:

db.contacts.find( { name: "xyz", email: { $regex: /\.org$/ } } )

No entanto, a query a seguir não pode usar o índice porque inclui uma correspondência nula no campo email, o que não é permitido pela expressão de filtro { email: { $exists: true } }:

db.contacts.find( { name: "xyz", email: { $exists: false } } )

Os índices parciais também podem ser índices TTL. Os índices TTL parciais correspondem à expressão do filtro especificada e expiram apenas esses documentos. Para obter detalhes, consulte Expirar documentos com condições de filtro.

A partir do MongoDB 5.0, vários índices parciais podem ser criados usando o mesmo padrão de chave, desde que os campos partialFilterExpression não expressem filtros equivalentes.

Nas versões anteriores do MongoDB, a criação de vários índices parciais não é permitida ao usar o mesmo padrão de chave com diferentes PartialFilterExpressions.

Você não pode especificar a opção partialFilterExpression e a opção sparse.

_id os índices não podem ser índices parciais.

Os índices de chave de shard não podem ser índices parciais.

Considere uma collection restaurants contendo documentos que se assemelham ao seguinte

{
"_id" : ObjectId("5641f6a7522545bc535b5dc9"),
"address" : {
"building" : "1007",
"coord" : [
-73.856077,
40.848447
],
"street" : "Morris Park Ave",
"zipcode" : "10462"
},
"borough" : "Bronx",
"cuisine" : "Bakery",
"rating" : { "date" : ISODate("2014-03-03T00:00:00Z"),
"grade" : "A",
"score" : 2
},
"name" : "Morris Park Bake Shop",
"restaurant_id" : "30075445"
}

Você pode adicionar um índice parcial nos campos borough e cuisine escolhendo somente para indexar documentos onde o campo rating.grade é A:

db.restaurants.createIndex(
{ borough: 1, cuisine: 1 },
{ partialFilterExpression: { 'rating.grade': { $eq: "A" } } }
)

Em seguida, a seguinte query na collection restaurants utiliza o índice parcial para retornar os restaurantes no Bronx com rating.grade igual a A:

db.restaurants.find( { borough: "Bronx", 'rating.grade': "A" } )

No entanto, a seguinte query não pode utilizar o índice parcial porque a expressão de query não inclui o campo rating.grade :

db.restaurants.find( { borough: "Bronx", cuisine: "Bakery" } )

Os índices parciais indexam apenas os documentos em uma collection que atendem a uma expressão de filtro especificada. Se você especificar a partialFilterExpression e uma restrição exclusiva, esta só se aplicará aos documentos que atenderem à expressão de filtro. Um índice parcial com uma restrição exclusiva não impede a inserção de documentos que não atendem à restrição exclusiva se os documentos não atenderem aos critérios do filtro.

Por exemplo, uma collection users contém os seguintes documentos:

{ "_id" : ObjectId("56424f1efa0358a27fa1f99a"), "username" : "david", "age" : 29 }
{ "_id" : ObjectId("56424f37fa0358a27fa1f99b"), "username" : "amanda", "age" : 35 }
{ "_id" : ObjectId("56424fe2fa0358a27fa1f99c"), "username" : "rajiv", "age" : 57 }

A seguinte operação cria um índice que especifica uma restrição exclusiva no campo username e uma expressão de filtro parcial age: { $gte: 21 }.

db.users.createIndex(
{ username: 1 },
{ unique: true, partialFilterExpression: { age: { $gte: 21 } } }
)

O índice impede a inserção dos seguintes documentos, pois já existem documentos com os nomes de usuário especificados e os campos age são maiores que 21:

db.users.insertMany( [
{ username: "david", age: 27 },
{ username: "amanda", age: 25 },
{ username: "rajiv", age: 32 }
] )

No entanto, os seguintes documentos com nomes de usuário duplicados são permitidos, pois a restrição exclusiva só se aplica a documentos com age maior ou igual a 21.

db.users.insertMany( [
{ username: "david", age: 20 },
{ username: "amanda" },
{ username: "rajiv", age: null }
] )

Voltar

Unique Indexes