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

Índices curinga

Nesta página

  • Criar Índice Curinga
  • Considerações
  • Comportamento
  • Restrições
  • Suporte de query/classificação de índice curinga

O MongoDB oferece suporte à criação de índices em um campo ou conjunto de campos para oferecer suporte a query. Como o MongoDB oferece suporte a esquemas dinâmicos, a aplicação pode executar query do campo cujos nomes não podem ser conhecidos antecipadamente ou são arbitrários.

Novidade na versão MongoDB: 4,2

O MongoDB 4.2 introduz índices curinga para apoiar query em campo desconhecidos ou arbitrários.

Considere um aplicativo que captura dados definidos pelo usuário no campo userMetadata e oferece suporte à consulta desses dados:

{ "userMetadata" : { "likes" : [ "dogs", "cats" ] } }
{ "userMetadata" : { "dislikes" : "pickles" } }
{ "userMetadata" : { "age" : 45 } }
{ "userMetadata" : "inactive" }

Os administradores desejam criar índices para dar suporte a query em qualquer subcampo de userMetadata.

Um índice curinga em userMetadata pode suportar query de campo único em userMetadata, userMetadata.likes, userMetadata.dislikes e userMetadata.age:

db.userData.createIndex( { "userMetadata.$**" : 1 } )

O índice suporta as seguintes queries:

db.userData.find({ "userMetadata.likes" : "dogs" })
db.userData.find({ "userMetadata.dislikes" : "pickles" })
db.userData.find({ "userMetadata.age" : { $gt : 30 } })
db.userData.find({ "userMetadata" : "inactive" })

Um índice não curinga em userMetadata só pode suportar query em valores de userMetadata.

Importante

Os índices curinga não são projetados para substituir o planejamento de índice baseado em volume de trabalho. Para obter mais informações sobre como criar índices para dar suporte a queries, consulte Criar índices para dar suporte a suas queries. Para obter a documentação completa sobre limitações de índice curinga , consulte Restrições de índice curinga.

Importante

O mongod featureCompatibilityVersion deve ser 4.2 para criar índices curinga. Para obter instruções sobre como definir o FCV, consulte Definir versão de compatibilidade do recurso em sistemas do MongoDB 5.0.

Você pode criar índices curinga utilizando o reconhecimento de data center createIndexes ou seu assistente de shell, createIndex() ou createIndexes().

Para indexar o valor de um campo específico:

db.collection.createIndex( { "fieldA.$**" : 1 } )

Com este índice curinga, o MongoDB indexa todos os valores de fieldA. Se um campo for um documento ou array aninhado, o índice curinga recorrerá ao documento/array e armazenará o valor de todos os campos no documento/array.

Por exemplo, documentos na collection product_catalog podem conter um campo product_attributes . O campo product_attributes pode conter campos aninhados arbitrários, incluindo documentos incorporados e arrays:

{
"product_name" : "Spy Coat",
"product_attributes" : {
"material" : [ "Tweed", "Wool", "Leather" ]
"size" : {
"length" : 72,
"units" : "inches"
}
}
}
{
"product_name" : "Spy Pen",
"product_attributes" : {
"colors" : [ "Blue", "Black" ],
"secret_feature" : {
"name" : "laser",
"power" : "1000",
"units" : "watts",
}
}
}

A seguinte operação cria um índice curinga no campo product_attributes :

db.products_catalog.createIndex( { "product_attributes.$**" : 1 } )

O índice curinga pode suportar query arbitrárias de campo único no product_attributes ou seus campo embutidos:

db.products_catalog.find( { "product_attributes.size.length" : { $gt : 60 } } )
db.products_catalog.find( { "product_attributes.material" : "Leather" } )
db.products_catalog.find( { "product_attributes.secret_feature.name" : "laser" } )

Observação

A sintaxe do índice curinga específico do caminho é incompatível com a opção wildcardProjection . Consulte as Opções para índices do wildcard para mais informações.

Para obter um exemplo, consulte Criar um Índice Curinga em um caminho do campo.

Para indexar o valor de todos os campos em um documento (excluindo _id), especifique "$**" como a chave do índice:

db.collection.createIndex( { "$**" : 1 } )

Com esse índice curinga, o MongoDB indexa todos os campo para cada documento na collection. Se um determinado campo for um documento ou array aninhada, o índice curinga recorrerá ao documento/array e armazenará o valor de todos os campos no documento/array.

Para obter um exemplo, consulte Criar um Índice Curinga em Todos os Field Paths.

Observação

Os índices curinga omitem o campo _id por padrão. Para incluir o campo _id no índice curinga, você deve explicitamente incluí-lo no documento wildcardProjection . Consulte Opções para índices wildcard para obter mais informações.

Para indexar os valores de vários campos específicos em um documento:

db.collection.createIndex(
{ "$**" : 1 },
{ "wildcardProjection" :
{ "fieldA" : 1, "fieldB.fieldC" : 1 }
}
)

Com esse índice curinga, o MongoDB indexa todos os valores para os campos especificados para cada documento na coleção. Se um determinado campo for um documento ou array aninhada, o índice curinga recorrerá ao documento/array e armazenará o valor de todos os campos no documento/array.

Observação

Os índices curinga não suportam a combinação de instruções de inclusão e exclusão no documento wildcardProjection , exceto quando se inclui explicitamente o campo _id . Para obter mais informações sobre wildcardProjection, consulte as Opções para índices wildcard .

Para obter um exemplo, consulte Incluir campos específicos na cobertura do índice curinga.

Para indexar o campo de todos os campos em um documento, excluindo caminhos de campo específicos:

db.collection.createIndex(
{ "$**" : 1 },
{ "wildcardProjection" :
{ "fieldA" : 0, "fieldB.fieldC" : 0 }
}
)

Com esse índice curinga, o MongoDB indexa todos os campo para cada documento na collection, excluindo os caminho do campo especificados. Se um determinado campo for um documento ou array aninhada, o índice curinga recorrerá ao documento/array e armazenará os valores de todos os campos no documento/array.

Para obter um exemplo, consulte Omitir campos específicos da cobertura do índice curinga.

Observação

Os índices curinga não suportam a combinação de instruções de inclusão e exclusão no documento wildcardProjection , exceto quando se inclui explicitamente o campo _id . Para obter mais informações sobre wildcardProjection, consulte as Opções para índices wildcard .

A partir do MongoDB 5.0, os índices curinga são normalizados após a criação, vários índices curinga podem ser criados usando o mesmo padrão de chave , desde que os campos wildcardProjection não Express filtros equivalentes.

Por exemplo, crie um índice curinga:

db.books.createIndex( { "$**" : 1 }, { wildcardProjection : {a: 1, "b.c": 1 } } )

Visualizar o índice com o método db.collection.getIndexes() :

db.books.getIndexes()

Os resultados são exibidos em um formato normalizado:

{ v: 2, key: { _id: 1 }, name: '_id_' },
{
v: 2,
key: { '$**': 1 },
name: '$**_1',
wildcardProjection: { a: true, b: { c: true }, _id: false }
}
  • Os índices curinga podem suportar no máximo um campo em qualquer predicado de query fornecido. Para obter mais informações sobre o suporte da query do índice curinga, consulte Suporte da query/classificação do índice curinga.

  • O mongod featureCompatibilityVersion deve ser 4.2 para criar índices curinga. Para obter instruções sobre como definir o FCV, consulte Definir versão de compatibilidade do recurso em sistemas do MongoDB 5.0.

  • Os índices curinga omitem o campo _id por padrão. Para incluir o campo _id no índice curinga, você deve explicitamente incluí-lo no documento curingaProjection (ou seja, { "_id" : 1 } ).

  • É possível criar múltiplos índices curinga em uma coleção.

  • Um índice curinga pode cobrir os mesmos campos que outros índices na collection.

  • Os índices curinga são índices esparsos e contêm apenas entradas para documentos que têm o campo indexado, mesmo que o campo de índice contenha um valor nulo.

Os índices curinga têm um comportamento específico ao indexar campos que são um objeto (ou seja, um documento incorporado) ou uma array:

  • Se o campo for um objeto, o índice curinga desce para o objeto e indexa seu conteúdo. O índice curinga continua descendo para quaisquer documentos incorporados adicionais que encontrar.

  • Se o campo for uma array, o índice curinga atravessará a array e indexará cada elemento:

    • Se um elemento na array for um objeto, o índice curinga desce até o objeto para indexar seu conteúdo, conforme descrito acima.

    • Se o elemento for uma array - ou seja, uma array incorporada diretamente na array principal -, o índice curinga não atravessará a array incorporada, mas indexará a array inteira como um único valor.

  • Para todos os outros campos, registre o valor primitivo (não objeto/array) no índice.

O índice curinga continua atravessando quaisquer objetos ou arrays aninhados adicionais até atingir um valor primitivo (ou seja, um campo que não é um objeto ou array). Em seguida, ele indexa esse valor primitivo, juntamente com o caminho completo para esse campo.

Por exemplo, considere o seguinte documento:

{
"parentField" : {
"nestedField" : "nestedValue",
"nestedObject" : {
"deeplyNestedField" : "deeplyNestedValue"
},
"nestedArray" : [
"nestedArrayElementOne",
[ "nestedArrayElementTwo" ]
]
}
}

Um índice curinga que inclui parentField registra as seguintes entradas:

  • "parentField.nestedField" : "nestedValue"

  • "parentField.nestedObject.deeplyNestedField" : "deeplyNestedValue"

  • "parentField.nestedArray" : "nestedArrayElementOne"

  • "parentField.nestedArray" : ["nestedArrayElementTwo"]

Observe que os registros de parentField.nestedArray não incluem a posição da array para cada elemento. Os índices curinga ignoram as posições dos elementos da array ao gravar o elemento no índice. Os índices curinga ainda podem suportar queries que incluem índices de array explícitos. Consulte Queries com índices de array explícitos para obter mais informações.

Para obter mais informações sobre o comportamento do índice curinga com objetos aninhados, consulte Objetos aninhados.

Para obter mais informações sobre o comportamento do índice curinga com arrays agrupadas, consulte Arrays agrupadas.

Quando um índice curinga encontra um objeto aninhado, ele desce até o objeto e indexa seu conteúdo. Por exemplo:

{
"parentField" : {
"nestedField" : "nestedValue",
"nestedArray" : ["nestedElement"]
"nestedObject" : {
"deeplyNestedField" : "deeplyNestedValue"
}
}
}

Um índice curinga que inclui parentField desce para o objeto para percorrer e indexar seu conteúdo:

  • Para cada campo que é um objeto (ou seja, um documento incorporado), desça ao objeto para indexar seu conteúdo.

  • Para cada campo que é uma array, percorra a array e indexe seu conteúdo.

  • Para todos os outros campos, registre o valor primitivo (não objeto/array) no índice.

O índice curinga continua atravessando quaisquer objetos ou arrays aninhados adicionais até atingir um valor primitivo (ou seja, um campo que não é um objeto ou array). Em seguida, ele indexa esse valor primitivo, juntamente com o caminho completo para esse campo.

Dado o documento de exemplo, o índice curinga adiciona os seguintes registros ao índice:

  • "parentField.nestedField" : "nestedValue"

  • "parentField.nestedObject.deeplyNestedField" : "deeplyNestedValue"

  • "parentField.nestedArray" : "nestedElement"

Para obter mais informações sobre o comportamento do índice curinga com arrays agrupadas, consulte Arrays agrupadas.

Quando um índice curinga encontra uma array agrupada, ele tenta atravessar a array para indexar seus elementos. Se a array for em si um elemento em uma array principal (ou seja, uma array incorporada), o índice curinga registrará a array inteira como um valor em vez de percorrer seu conteúdo. Por exemplo:

{
"parentArray" : [
"arrayElementOne",
[ "embeddedArrayElement" ],
"nestedObject" : {
"nestedArray" : [
"nestedArrayElementOne",
"nestedArrayElementTwo"
]
}
]
}

Um índice curinga que inclui parentArray desce para a array para percorrer e indexar seu conteúdo:

  • Para cada elemento que é uma array (ou seja, uma array embutida), indexe a array inteira como um valor.

  • Para cada elemento que é um objeto, desça ao objeto para percorrer e indexar seu conteúdo.

  • Para todos os outros campos, registre o valor primitivo (não objeto/array) no índice.

O índice curinga continua atravessando quaisquer objetos ou arrays aninhados adicionais até atingir um valor primitivo (ou seja, um campo que não é um objeto ou array). Em seguida, ele indexa esse valor primitivo, juntamente com o caminho completo para esse campo.

Dado o documento de exemplo, o índice curinga adiciona os seguintes registros ao índice:

  • "parentArray" : "arrayElementOne"

  • "parentArray" : ["embeddedArrayElement"]

  • "parentArray.nestedObject.nestedArray" : "nestedArrayElementOne"

  • "parentArray.nestedObject.nestedArray" : "nestedArrayElementTwo"

Observe que os registros de parentField.nestedArray não incluem a posição da array para cada elemento. Os índices curinga ignoram as posições dos elementos da array ao gravar o elemento no índice. Os índices curinga ainda podem suportar queries que incluem índices de array explícitos. Consulte Queries com índices de array explícitos para obter mais informações.

Dica

Veja também:

A partir do MongoDB 5.0.16, o campo wildcardProjection armazena a projeção do índice na forma enviada. Versões anteriores do servidor podem ter armazenado a projeção de forma normalizada.

O servidor utiliza o índice da mesma maneira, mas você pode notar uma diferença na saída dos comandos listIndexes e db.collection.getIndexes() .

  • Você não pode fragmentar uma collection usando um índice curinga. Crie um índice não curinga no campo ou campos que você deseja fragmentar. Para obter mais informações sobre a seleção de chaves de shard, consulte Chaves de Shard.

  • Não é possível criar um índice composto .

  • Não é possível especificar as seguintes propriedades para um índice curinga:

  • Não é possível criar os seguintes tipos de índice utilizando a sintaxe curinga:

Importante

Os índices curinga são distintos e incompatíveis com os índices de texto curinga. Os índices curinga não suportam consultas usando o operador $text .

Para obter a documentação completa sobre restrições de criação de índice curinga, consulte Tipos de índice ou propriedades incompatíveis.

Os índices curinga poderão suportar uma consulta coberta somente se todos os itens a seguir forem verdadeiros:

  • O planejador de query seleciona o índice curinga para satisfazer o predicado da query.

  • O predicado de consulta especifica exatamente um campo coberto pelo índice curinga.

  • A projeção exclui explicitamente o _id e inclui somente o campo de query.

  • O campo de consulta especificado nunca é uma matriz.

Considere o seguinte índice curinga na collection employees:

db.products.createIndex( { "$**" : 1 } )

A seguinte operação faz uma consulta para um campo único lastName e projeta todos os outros campos a partir do documento resultante:

db.products.find(
{ "lastName" : "Doe" },
{ "_id" : 0, "lastName" : 1 }
)

Supondo que o lastName especificado nunca seja uma array, o MongoDB pode usar o índice curinga $** para oferecer suporte a uma query coberta.

Os índices curinga podem suportar no máximo um campo de predicado de query. Ou seja:

  • O MongoDB não pode usar um índice não curinga para satisfazer uma parte de um predicado de query e um índice curinga para satisfazer outro.

  • O MongoDB não pode usar um índice curinga para satisfazer uma parte de um predicado de query e outro índice curinga para satisfazer outro.

  • Mesmo que um único índice curinga possa suportar vários campos de query, o MongoDB pode usar o índice curinga para suportar apenas um dos campos de query. Todos os campos restantes são resolvidos sem um índice.

No entanto, o MongoDB pode usar o mesmo índice curinga para satisfazer cada argumento independente dos operadores de query $or ou aggregation $or .

O MongoDB pode usar um índice curinga para satisfazer sort() somente se todas as condições a seguir forem verdadeiras:

  • O planejador de query seleciona o índice curinga para satisfazer o predicado da query.

  • O sort() especifica somente o campo de predicado da query.

  • O campo especificado nunca é uma matriz.

Se as condições acima não forem atendidas, o MongoDB não poderá usar o índice curinga para a classificação. O MongoDB não suporta operações do sort() que exigem um índice diferente do do predicado de query. Para obter mais informações, consulte Interseção e classificação de índices.

Considere o seguinte índice curinga na collection products:

db.products.createIndex( { "product_attributes.$**" : 1 } )

A seguinte operação faz queries para um campo único product_attributes.price e classifica neste mesmo campo:

db.products.find(
{ "product_attributes.price" : { $gt : 10.00 } },
).sort(
{ "product_attributes.price" : 1 }
)

Supondo que o price especificado nunca seja uma array, o MongoDB pode usar o índice curinga product_attributes.$** para satisfazer tanto find() quanto sort().

Os índices curinga não podem suportar os seguintes padrões de query:

  • Query que verificam se um campo não existe

  • Query que verificam se um campo é ou não igual a um documento ou array

  • Query que verificam se um campo é igual a nulo

Para obter detalhes, consulte Padrões de query e aggregation não suportados.

Os índices curinga do MongoDB não registram a posição da array de nenhum elemento específico em uma array durante a indexação. No entanto, o MongoDB ainda pode selecionar o índice curinga para responder a uma query que inclui um caminho do campo com um ou mais índices de array explícitos (por exemplo, parentArray.0.nestedArray.0). Devido à crescente complexidade de definir limites de índice para cada array aninhada consecutiva, o MongoDB não considera que o índice curinga responda a um determinado caminho do campo na query se esse caminho contiver mais de 8 índices de array explícitos. O MongoDB ainda pode considerar o índice curinga para responder a outros caminhos de campo na query.

Por exemplo:

{
"parentObject" : {
"nestedArray" : [
"elementOne",
{
"deeplyNestedArray" : [ "elementTwo" ]
}
]
}
}

O MongoDB pode selecionar um índice curinga que inclua parentObject para satisfazer as seguintes query:

  • "parentObject.nestedArray.0" : "elementOne"

  • "parentObject.nestedArray.1.deeplyNestedArray.0" : "elementTwo"

Se um determinado caminho do campo no predicado de query especificar mais de 8 índices de array explícitos, o MongoDB não considerará o índice curinga para responder a esse caminho do campo. Em vez disso, o MongoDB seleciona outro índice elegível para responder à query ou executa uma varredura de collection.

Observe que os índices curinga em si não têm limites na profundidade com que atravessam um documento enquanto o indexam; a limitação se aplica apenas a query que especificam explicitamente índices de array exatos. Ao emitir as mesmas queries sem os índices de array explícitos, o MongoDB pode selecionar o índice curinga para responder à query:

  • "parentObject.nestedArray" : "elementOne"

  • "parentObject.nestedArray.deeplyNestedArray" : "elementTwo"

Voltar

Limites de índice de várias chaves