Índices Curinga em Objetos e Matrizes Incorporados
Os índices curinga têm um comportamento específico ao indexar campos de objeto e arrays incorporados:
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 o elemento for um objeto, o índice curinga desce até o objeto para indexar seu conteúdo.
Se o elemento for uma array (ou seja, uma array incorporada diretamente à 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, o índice armazena o valor primitivo. Um valor primitivo é um valor não objeto, valor não array.
O índice curinga continua atravessando quaisquer objetos ou arrays incorporados adicionais até atingir um valor primitivo. Em seguida, indexa o valor primitivo, juntamente com o caminho completo para esse campo.
Índices curinga em objetos embarcados
Quando um índice curinga encontra um objeto embarcado, ele desce até o objeto e indexa seu conteúdo. Por exemplo, considere este documento:
db.users.insertOne( { account: { username: "SuperAdmin01", contact: { phone: "123-456-7890", email: "xyz@example.com" }, access: { group: "admin" } } } )
Um índice curinga que inclui o campo account
desce para o objeto account
para percorrer e indexar seu conteúdo:
Para cada subcampo que é em si um objeto (por exemplo,
account.contact
eaccount.access
), o índice desce para o objeto e registra seu conteúdo.Para todos os outros subcampos, o índice registra o valor primitivo no índice.
Dado o documento de exemplo, o índice curinga adiciona os seguintes registros ao índice:
"account.username" : "SuperAdmin01"
"account.contact.phone" : "123-456-7890"
"account.contact.email" : "xyz@example.com"
"account.access.group" : "admin"
Índices curinga em arrays
Quando um índice curinga encontra uma array, ele atravessa a array para indexar seus elementos. Se o elemento de array for ele mesmo uma array (um array embutido), o índice registrará todo o array embutido como um valor em vez de percorrer seu conteúdo.
Por exemplo, considere este documento:
db.fleet.insertOne( { "ship": { "coordinates" : [ [-5, 10], [-7, 8] ], "type": "Cargo Ship", "captains": [ { "name": "Francis Drake", "crew": [ "first mate", "carpenter" ] } ] } } )
Um índice curinga que inclui o campo ship
desce para o objeto para percorrer e indexar seu conteúdo:
Para cada elemento que é uma array:
Se o elemento for em si uma array (como em uma array embutida), o índice registrará a array inteira como um valor.
Se o elemento for um objeto, o índice desce até o objeto para percorrer e indexar seu conteúdo.
Se o elemento for um valor primitivo, o índice registrará esse valor.
Para campos sem array e não objeto, o índice registra o valor primitivo no índice.
Dado o documento de exemplo, o índice curinga adiciona os seguintes registros ao índice:
"ship.coordinates" : [-5, 10]
"ship.coordinates" : [-7, 8]
"ship.type" : "Cargo Ship"
"ship.captains.name" : "Francis Drake"
"ship.captains.crew" : "first mate"
"ship.captains.crew" : "carpenter"
Consultas com índices de array explícitos
Os índices curinga 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 usar o índice curinga para atender a uma query que inclua um caminho de campo com um ou mais índices de array explícitos.
Por exemplo, considere este documento:
db.fleet.insertOne( { "ship": { "coordinates" : [ [-5, 10], [-7, 8] ], "type": "Cargo Ship", "captains": [ { "name": "Francis Drake", "crew": [ "first mate", "carpenter" ] } ] } } )
Crie um índice curinga que inclua o campo ship
:
db.fleet.createIndex( { "ship.$**": 1 } )
Os registros de índice para ship.coordinates
e ship.captains
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. No entanto, os índices curinga ainda podem suportar consultas que incluem índices de array explícitos.
O MongoDB pode usar o índice curinga para atender a esta query:
db.fleet.find( { "ship.captains.0.name": "Francis Drake" } )
A query retorna o documento de exemplo:
[ { _id: ObjectId("6350537db1fac2ee2e957efc"), ship: { coordinates: [ [ -5, 10 ], [ -7, 8 ] ], type: 'Cargo Ship', captains: [ { name: 'Francis Drake', crew: [ 'first mate', 'carpenter' ] } ] } } ]
O MongoDB não pode usar o índice curinga para atender a esta consulta:
db.fleet.find( { "ship.coordinates.0.1": 10 } )
O campo ship.coordinates
contém arrays incorporados. Os índices curinga não registram valores individuais de arrays incorporados. Em vez disso, eles registram toda a array incorporada. Como resultado, o índice curinga não pode suportar uma correspondência em um valor de array incorporado, e o MongoDB atende à query com uma varredura de collection.
Limitação do índice do array
O MongoDB só pode usar um índice curinga para preencher um determinado caminho de campo na query se o caminho contiver 8 ou menos índices de array explícitos. Se o caminho do campo contiver mais de 8 índices explícitos, para atender à query, o MongoDB ou:
Seleciona outro índice elegível.
Executa uma verificação da collection.
Os índices curinga em si não têm limites na profundidade em que atravessam um documento enquanto o indexam. A limitação se aplica apenas a queries que especificam explicitamente índices de array exatos.