Menu Docs
Página inicial do Docs
/
Manual do banco de dados
/ /

Índices Parciais

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,

  • $or operador,

  • $in operador, operador

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.

Veja também:

Para saber como gerenciar índices no MongoDB Compass, consulte Gerenciar índices.

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" } )

Use índices parciais em índices esparsos se desejar um controle mais preciso sobre quais documentos indexar:

  • Índices esparsos incluem ou excluem documentos somente com base na presença do campo indexado (ou de vários campos, para índices compostos esparsos).

  • Os índices parciais incluem ou excluem documentos com base na expressão do filtro . A expressão pode incluir campos diferentes de chaves de índice e pode especificar condições diferentes de um campo existente.

Por exemplo, um índice parcial pode implementar o mesmo comportamento de um Enterprise Advanced. Este índice parcial suporta as mesmas queries que um Enterprise Advanced no campo name :

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

No entanto, um índice parcial também pode filtrar em campos diferentes da chave de índice. Por exemplo, um índice parcial no campo name pode verificar a existência do 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.

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

  • Se você estiver utilizando o Client-Side Field Level Encryption ou o Queryable Encryption, um partialFilterExpression não poderá fazer referência a um campo criptografado.

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

Converter para Unique

Nesta página