Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
APLICA-SE A:
MongoDB vCore
Os índices são estruturas que melhoram a velocidade de recuperação de dados, permitindo o acesso rápido a campos específicos dentro de uma coleção. Este artigo explica como executar a indexação em vários níveis de aninhamento e analisa como revisar efetivamente a utilização desses índices.
Cenários de indexação
Trabalharíamos com cenários de exemplo com contexto para o JSON de amostra definida.
{
"_id": "e79b564e-48b1-4f75-990f-e62de2449239",
"car_id":"AZ-9874532",
"car_info": {
"make": "Mustang",
"model": "GT Fastback",
"year": 2024,
"registration": {
"license_plate": "LJX386",
"state": "WV",
"registration_datetime": {
"$date": "2024-01-10T01:16:44.000Z"
},
"expiration_datetime": {
"$date": "2034-01-10T01:16:44.000Z"
}
}
},
"rental_history": [
{
"rental_id": "RT63857499825952",
"customer_id": "CX8716",
"start_date": {
"$date": "2024-02-29T01:16:44.000Z"
},
"end_date": {
"$date": "2024-03-04T16:54:44.000Z"
},
"pickup_location": { "type": "Point", "coordinates": [ -73.97, 40.77 ]
},
"drop_location": { "type": "Point", "coordinates": [ -73.96, 40.78 ]
},
"total_price": 232.56944444444443,
"daily_rent": 50,
"complains": [
{
"complain_id": "CMP638574998259520",
"issue": "Strange odor inside the car.",
"reported_datetime": {
"$date": "2024-03-03T20:11:44.000Z"
},
"reported_medium": "Website",
"resolutions": [
{
"resolution_datetime": {
"$date": "2024-03-03T20:20:44.000Z"
},
"solution": "Inspect for any leftover food, spills, or trash that might be causing the odor. Contact the rental agency.",
"resolved": true
}
]
}
],
"accidents": [
{
"accident_id": "ACC376184",
"date": {
"$date": "2024-03-03T01:47:44.000Z"
},
"description": "Collisions with Soft Barriers: Accidents involving hitting bushes, shrubs, or other soft barriers.",
"repair_cost": 147
}
]
},
{
"rental_id": "RT63857499825954",
"customer_id": "CX1412",
"start_date": {
"$date": "2033-11-18T01:16:44.000Z"
},
"end_date": {
"$date": "2033-11-25T21:11:44.000Z"
},
"pickup_location": { "type": "Point", "coordinates": [ 40, 5 ]
},
"drop_location": { "type": "Point", "coordinates": [ 41, 11 ]
},
"total_price": 305.3645833333333,
"daily_rent": 39,
"complains": [
{
"complain_id": "CMP638574998259540",
"issue": "Unresponsive infotainment system.",
"reported_datetime": {
"$date": "2033-11-19T17:55:44.000Z"
},
"reported_medium": "Agency",
"resolutions": []
}
],
"accidents": null
}
],
"junk": null
}
Indexação do campo raiz
O Azure Cosmos DB para MongoDB vCore permite índices em propriedades raiz. O exemplo permite pesquisar sampleColl
por car_id
.
CarData> db.sampleColl.createIndex({"car_id":1})
O plano de execução permite rever a utilização do índice criado no campo car_id
utilizando explain
.
CarData> db.sampleColl.find({"car_id":"ZA-XWB804"}).explain()
{
explainVersion: 2,
command: "db.runCommand({explain: { 'find' : 'sampleColl', 'filter' : { 'car_id' : 'ZA-XWB804' } }})",
explainCommandPlanningTimeMillis: 0.156,
explainCommandExecTimeMillis: 37.956,
dataSize: '32 kB',
queryPlanner: {
namespace: 'CarData.sampleColl',
winningPlan: {
stage: 'FETCH',
estimatedTotalKeysExamined: 8700,
inputStage: {
stage: 'IXSCAN',
indexName: 'car_id_1',
isBitmap: true,
indexFilterSet: [ { '$eq': { car_id: 'ZA-XWB804' } } ],
estimatedTotalKeysExamined: 174
}
}
},
ok: 1
}
Indexando as propriedades aninhadas
O Azure Cosmos DB para MongoDB vCore permite indexar propriedades de documentos incorporados. O exemplo cria um índice no campo registration_datetime
dentro de um documento aninhado registration
.
CarData> db.sampleColl.createIndex({"car_info.registration.registration_datetime":1})
Revise o plano de execução com explain
oferece uma visão sobre a verificação de índice.
CarData> db.sampleColl.find({"car_info.registration.registration_datetime":
{ $gte : new ISODate("2024-05-01")
,$lt: ISODate("2024-05-07")
}
}).explain()
{
explainVersion: 2,
command: "db.runCommand({explain: { 'find' : 'sampleColl', 'filter' : { 'car_info.registration.registration_datetime' : { '$gte' : ISODate('2024-05-01T00:00:00Z'), '$lt' : ISODate('2024-05-07T00:00:00Z') } } }})",
explainCommandPlanningTimeMillis: 0.095,
explainCommandExecTimeMillis: 42.703,
dataSize: '4087 kB',
queryPlanner: {
namespace: 'CarData.sampleColl',
winningPlan: {
stage: 'FETCH',
estimatedTotalKeysExamined: 4350,
inputStage: {
stage: 'IXSCAN',
indexName: 'car_info.registration.registration_datetime_1',
isBitmap: true,
indexFilterSet: [
{
'$range': {
'car_info.registration.registration_datetime': {
min: ISODate("2024-05-01T00:00:00.000Z"),
max: ISODate("2024-05-07T00:00:00.000Z"),
minInclusive: true,
maxInclusive: false
}
}
}
],
estimatedTotalKeysExamined: 2
}
}
},
ok: 1
}
Indexação das arrays na raiz
O Azure Cosmos DB para MongoDB vCore permite indexar a propriedade raiz definida como uma matriz. Vamos considerar a seguinte amostra JSON.
{
"_id": ObjectId("58f56170ee9d4bd5e610d644"),
"id": 1,
"num": 001,
"name": "Bulbasaur",
"img": "http://www.serebii.net/pokemongo/pokemon/001.png",
"type": [ 'Grass', 'Poison' ],
"height": '0.71 m',
"weight": '6.9 kg',
"avg_spawns": 69,
"spawn_time": "20:00",
"multipliers": [ 1.58 ],
"weaknesses": [ "Fire", "Ice", "Flying", "Psychic"],
"next_evolution": [ { "num": "002", "name": "Ivysaur" }, { "num": "003", "name": "Venusaur" }]
}
Em nosso exemplo, criamos um índice no weaknesses
campo de matriz e estamos analisando a existência de todos os três valores Ground
, Water
& Fire
na matriz.
Cosmicworks> db.Pokemon.createIndex({'weaknesses':1})
Cosmicworks> db.Pokemon.find({"weaknesses":
{$all:["Ground","Water","Fire"]}
}
).explain()
{
explainVersion: 2,
command: "db.runCommand({explain: { 'find' : 'Pokemon', 'filter' : { 'weaknesses' : { '$all' : ['Ground', 'Water', 'Fire'] } } }})",
explainCommandPlanningTimeMillis: 10.161,
explainCommandExecTimeMillis: 21.64,
dataSize: '906 bytes',
queryPlanner: {
namespace: 'Cosmicworks.Pokemon',
winningPlan: {
stage: 'FETCH',
estimatedTotalKeysExamined: 50,
inputStage: {
stage: 'IXSCAN',
indexName: 'weaknesses_1',
isBitmap: true,
indexFilterSet: [
{ '$all': { weaknesses: [ 'Ground', 'Water', 'Fire' ] } }
],
estimatedTotalKeysExamined: 2
}
}
},
ok: 1
}
Nota
Para MongoServerError: A chave de índice é muito grande.
Crie uma solicitação de suporte para habilitar a indexação em segundo plano, seguida por enableLargeIndexKeys
db.runCommand({ createIndexes: "collectionName", indexes: [{ {"index_spec"}], enableLargeIndexKeys: true });
Indexação de matrizes aninhadas
O Azure Cosmos DB para MongoDB vCore permite indexar matrizes aninhadas. O exemplo cria um índice no resolutions
campo existente na complains
matriz.
CarData> db.sampleColl.createIndex({"rental_history.complains.resolutions":1})
Revisamos o plano com explain
para identificar todos os arrendamentos, sem fornecer uma resolução ao cliente.
CarData> db.sampleColl.find({"rental_history.complains.resolutions":{ $exists: false, $ne: []}}).explain()
{
explainVersion: 2,
command: "db.runCommand({explain: { 'find' : 'sampleColl', 'filter' : { 'rental_history.complains.resolutions' : { '$exists' : false, '$ne' : [] } } }})",
explainCommandPlanningTimeMillis: 0.12,
explainCommandExecTimeMillis: 48.721000000000004,
dataSize: '1747 kB',
queryPlanner: {
namespace: 'CarData.sampleColl',
winningPlan: {
stage: 'FETCH',
estimatedTotalKeysExamined: 1933,
inputStage: {
stage: 'IXSCAN',
indexName: 'rental_history.complains.resolutions_1',
isBitmap: true,
indexFilterSet: [
{
'$exists': { 'rental_history.complains.resolutions': false }
},
{ '$ne': { 'rental_history.complains.resolutions': [] } }
],
estimatedTotalKeysExamined: 2
}
}
},
ok: 1
}
Indexação de campo específico em uma matriz
O Azure Cosmos DB para MongoDB vCore permite a indexação de campos dentro de uma matriz. O exemplo cria um índice no date
campo dentro da accidents
matriz.
CarData> db.sampleColl.createIndex({"rental_history.accidents.date":1})
A consulta de exemplo avalia os acidentes num intervalo de tempo e mostra o índice criado na propriedade date
que está a ser utilizado.
CarData> db.sampleColl.find({"rental_history.accidents.date":
{ $gte : ISODate("2024-05-01")
, $lt : ISODate("2024-05-07")
}
}).explain()
{
explainVersion: 2,
command: "db.runCommand({explain: { 'find' : 'sampleColl', 'filter' : { 'rental_history.accidents.date' : { '$gte' : ISODate('2024-05-01T00:00:00Z'), '$lt' : ISODate('2024-05-07T00:00:00Z') } } }})",
explainCommandPlanningTimeMillis: 19.816,
explainCommandExecTimeMillis: 48.359,
dataSize: '12 MB',
queryPlanner: {
namespace: 'CarData.sampleColl',
winningPlan: {
stage: 'FETCH',
estimatedTotalKeysExamined: 4350,
inputStage: {
stage: 'IXSCAN',
indexName: 'rental_history.accidents.date_1',
isBitmap: true,
indexFilterSet: [
{
'$range': {
'rental_history.accidents.date': {
min: ISODate("2024-05-01T00:00:00.000Z"),
max: ISODate("2024-05-07T00:00:00.000Z"),
minInclusive: true,
maxInclusive: false
}
}
}
],
estimatedTotalKeysExamined: 2
}
}
},
ok: 1
}
Nota
No momento, estamos aprimorando o suporte para arrays aninhados. Em certos casos limite, operações de indexação específicas podem levar a erros.
Indexação de curingas ao excluir campos aninhados
O Azure Cosmos DB para MongoDB vCore dá suporte a índices curinga. O exemplo nos permite excluir a indexação de todos os campos aninhados no documento car_info
.
// Excludes all the nested sub-document property
CarData> db.sampleColl.createIndex( {"$**":1}
,{"wildcardProjection":
{ "car_info.make":0
,"car_info.model":0
,"car_info.registration":0
,"car_info.year":0
,"rental_history":0
}
}
)
O plano de execução não mostra suporte para consultas realizadas no model
campo, que foi excluído durante a criação do índice Curinga.
CarData> db.sampleColl.find({"car_info.model":"GT Fastback"}).explain()
{
explainVersion: 2,
command: "db.runCommand({explain: { 'find' : 'sampleColl', 'filter' : { 'car_info.model' : 'GT Fastback' } }})",
explainCommandPlanningTimeMillis: 10.879,
explainCommandExecTimeMillis: 374.25100000000003,
dataSize: '0 bytes',
queryPlanner: {
namespace: 'CarData.sampleColl',
winningPlan: {
stage: 'COLLSCAN',
runtimeFilterSet: [ { '$eq': { 'car_info.model': 'GT Fastback' } } ],
estimatedTotalKeysExamined: 8700
}
},
ok: 1
}
Indexação usando caracteres universais enquanto exclui objetos aninhados
O Azure Cosmos DB para MongoDB vCore dá suporte a índices curinga. O exemplo nos permite excluir objetos aninhados do documento.
// Wildcard index excluding nested object
[mongos] CarData> db.sampleColl.createIndex( {"$**":1},
{"wildcardProjection":
{ "car_info":0
,"rental_history":0
}
}
)
O plano de execução não mostra suporte para consultas realizadas em campo make
aninhado dentro do car_info
documento.
CarData> db.sampleColl.find({"car_info.make":"Mustang"}).explain()
{
explainVersion: 2,
command: "db.runCommand({explain: { 'find' : 'sampleColl', 'filter' : { 'car_info.make' : 'Mustang' } }})",
explainCommandPlanningTimeMillis: 21.271,
explainCommandExecTimeMillis: 337.475,
dataSize: '0 bytes',
queryPlanner: {
namespace: 'CarData.sampleColl',
winningPlan: {
stage: 'COLLSCAN',
runtimeFilterSet: [ { '$eq': { 'car_info.make': 'Mustang' } } ],
estimatedTotalKeysExamined: 8700
}
},
ok: 1
}
Indexação curinga ao excluir campos com matriz aninhada
O exemplo de índice curinga permite excluir campos da matriz aninhada. Utilizamos pokemon
coleção com formato json realçado.
{
{
"_id": ObjectId("58f56170ee9d4bd5e610d644"),
"id": 1,
"num": 001,
"name": "Bulbasaur",
"img": "http://www.serebii.net/pokemongo/pokemon/001.png",
"type": [ 'Grass', 'Poison' ],
"height": '0.71 m',
"weight": '6.9 kg',
"avg_spawns": 69,
"spawn_time": "20:00",
"multipliers": [ 1.58 ],
"weaknesses": [ "Fire", "Ice", "Flying", "Psychic"],
"next_evolution": [ { "num": "002", "name": "Ivysaur" }, { "num": "003", "name": "Venusaur" }]
}
}
Estamos criando índice em todos os campos dentro do json, excluindo a num
e name
campos de dentro de uma matriz.
Cosmicworks> db.Pokemon.createIndex( {"$**":1},
{"wildcardProjection":
{ "id":0
,"name":0
,"multipliers":0
,"next_evolution.num":0
,"next_evolution.name":0
}
}
)
O plano de explicação não mostra nenhuma utilização de índice durante a consulta no campo name
dentro do array next_evolution
.
Cosmicworks> db.Pokemon.find({"next_evolution.name":"Venusaur"}).explain()
{
explainVersion: 2,
command: "db.runCommand({explain: { 'find' : 'Pokemon', 'filter' : { 'next_evolution.name' : 'Venusaur' } }})",
explainCommandPlanningTimeMillis: 0.799,
explainCommandExecTimeMillis: 0.869,
dataSize: '1090 bytes',
queryPlanner: {
namespace: 'Cosmicworks.Pokemon',
winningPlan: {
stage: 'COLLSCAN',
runtimeFilterSet: [ { '$eq': { 'next_evolution.name': 'Venusaur' } } ],
estimatedTotalKeysExamined: 76
}
},
ok: 1
}
Próximos passos
- Saiba aqui sobre indexação de caracteres universais.
- Saiba mais sobre as melhores práticas de indexação para resultados mais eficientes.
- Saiba mais sobre a indexação em segundo plano
- Aprenda aqui a trabalhar com indexação de texto.