Los índices comodín tienen un comportamiento específico al indexación objetos incrustados y campos de arreglos:
Si el campo es un objeto, el índice comodín desciende al objeto e indexa su contenido. El índice comodín sigue descendiendo en cualquier documento incrustado adicional que encuentre.
Si el campo es un arreglo, el índice de comodín recorre el arreglo e indexa cada elemento:
Si el elemento es un objeto, el índice comodín desciende dentro del objeto para indexar su contenido.
Si el elemento es un arreglo (es decir, un arreglo que está incrustado directamente dentro del arreglo principal), el índice comodín no recorre el arreglo incrustado, sino que indexa el arreglo completo como un valor único.
Para todos los demás campos, el índice almacena el valor primitivo. Un valor primitivo es un valor que no es ni objeto ni arreglo.
El índice comodín continúa recorriendo cualquier objeto incrustado o arreglo adicional hasta que alcanza un valor primitivo. Luego indexa el valor primitivo, junto con la ruta completa a ese campo.
Índices comodín en objetos incrustados
Cuando un índice comodín encuentra un objeto incrustado, desciende en el objeto e indexa su contenido. Por ejemplo, considera este documento:
db.users.insertOne( { account: { username: "SuperAdmin01", contact: { phone: "123-456-7890", email: "xyz@example.com" }, access: { group: "admin" } } } )
Un índice comodín que incluye el account el campo desciende al objeto account para recorrer e indexar su contenido:
Para cada subcampo que sea en sí mismo un objeto (por ejemplo,
account.contactyaccount.access), el índice desciende en el objeto y registra su contenido.Para todos los demás subcampos, el índice registra el valor primitivo en el índice.
Dado el documento de muestra, el índice comodín agrega los siguientes registros al índice:
"account.username" : "SuperAdmin01""account.contact.phone" : "123-456-7890""account.contact.email" : "xyz@example.com""account.access.group" : "admin"
Índices comodín en arreglos
Cuando un índice comodín encuentra un arreglo, recorre el arreglo para indexar sus elementos. Si el elemento del arreglo es en sí mismo un arreglo (un arreglo incrustado), el índice registra todo el arreglo incrustado como un valor en lugar de recorrer su contenido.
Por ejemplo, considere este documento:
db.fleet.insertOne( { "ship": { "coordinates" : [ [-5, 10], [-7, 8] ], "type": "Cargo Ship", "captains": [ { "name": "Francis Drake", "crew": [ "first mate", "carpenter" ] } ] } } )
Un índice comodín que incluye el campo ship desciende en el objeto para recorrer e indexar su contenido:
Para cada elemento que sea un arreglo:
Si el elemento en sí es un arreglo (como en un arreglo incrustado), el índice registra todo el arreglo como un valor.
Si el elemento es un objeto, el índice desciende al objeto para recorrer e indexar su contenido.
Si el elemento es un valor primitivo, el índice registra ese valor.
Para los campos que no son arreglo ni objeto, el índice registra el valor primitivo en el índice.
Dado el documento de muestra, el índice comodín agrega los siguientes registros al í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 con índices de arreglo explícitos
Los índices comodín no registran la posición de ningún elemento en un arreglo durante la indexación. Sin embargo, MongoDB aún puede utilizar el índice comodín para cumplir con una query que incluya una ruta de campo con uno o más índices de arreglo explícitos.
Por ejemplo, considere este documento:
db.fleet.insertOne( { "ship": { "coordinates" : [ [-5, 10], [-7, 8] ], "type": "Cargo Ship", "captains": [ { "name": "Francis Drake", "crew": [ "first mate", "carpenter" ] } ] } } )
Crea un índice comodín que incluya el campo ship:
db.fleet.createIndex( { "ship.$**": 1 } )
Los registros del índice de ship.coordinates y ship.captains no incluyen la posición del arreglo para cada elemento. Los índices comodín ignoran las posiciones de los elementos de un arreglo al registrar el elemento en el índice. Sin embargo, los índices comodín aún pueden admitir queries que incluyan índices de arreglo explícitos.
MongoDB puede usar el índice comodín para cumplir con esta consulta:
db.fleet.find( { "ship.captains.0.name": "Francis Drake" } )
La query devuelve el documento de muestra:
[ { _id: ObjectId("6350537db1fac2ee2e957efc"), ship: { coordinates: [ [ -5, 10 ], [ -7, 8 ] ], type: 'Cargo Ship', captains: [ { name: 'Francis Drake', crew: [ 'first mate', 'carpenter' ] } ] } } ]
MongoDB no puede usar el índice comodín para completar esta query:
db.fleet.find( { "ship.coordinates.0.1": 10 } )
El campo ship.coordinates contiene arreglos embebidos. Los índices comodín no registran valores individuales de arreglos embebidos. En su lugar, registran todo el arreglo embebido. Como resultado, el índice comodín no puede soportar una coincidencia en un valor de arreglo embebido, y MongoDB cumple la query con un escaneo de colección.
Limitación del índice de arreglo
MongoDB solo puede utilizar un índice comodín para satisfacer una ruta de campo determinada en la query si la ruta contiene 8 o menos índices explícitos de arreglo. Si la ruta del campo contiene más de 8 índices explícitos, para cumplir la query, MongoDB:
Selecciona otro índice elegible.
Realiza un escaneo de colección.
Los índices comodín en sí mismos no tienen límites en la profundidad a la que recorren un documento durante su indexación. La limitación solo se aplica a las consultas que especifican explícitamente índices exactos de arreglos.