Remarque
L’accès à cette page requiert une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page requiert une autorisation. Vous pouvez essayer de modifier des répertoires.
Les index sont des structures qui améliorent la vitesse de récupération des données en permettant un accès rapide à des champs spécifiques au sein d’une collection. Cet article explique comment effectuer l’indexation à différents niveaux d’imbrication et passe en revue comment examiner efficacement l’utilisation de ces index.
Scénarios d’indexation
Nous allons travailler sur des exemples de scénarios en lien avec le contexte du fichier JSON d'échantillon défini.
{
"_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
}
Indexation du champ racine
Azure DocumentDB autorise les index sur les propriétés racines. L’exemple autorise la recherche sampleColl par car_id.
CarData> db.sampleColl.createIndex({"car_id":1})
Le plan d’exécution permet d’examiner l’utilisation de l’index créé sur le champ car_id avec 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
}
Indexation des propriétés imbriquées
Azure DocumentDB permet l’indexation des propriétés de document incorporées. L’exemple crée un index sur le champ registration_datetime dans un document registrationimbriqué.
CarData> db.sampleColl.createIndex({"car_info.registration.registration_datetime":1})
La vérification du plan d’exécution avec explain fournit des insights sur l’analyse d’index.
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
}
Indexation des tableaux à la racine
Azure DocumentDB permet d’indexer la propriété racine définie en tant que tableau. Prenons l’exemple json suivant.
{
"_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" }]
}
Dans notre exemple, nous créons un index sur weaknesses le champ de tableau et nous examinons l’existence des trois valeurs Ground, Water et Fire dans le tableau.
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
}
Note
Pour MongoServerError : la clé d’index est trop grande.
Créez une demande de support pour activer l’indexation en arrière-plan, suivie de enableLargeIndexKeys
db.runCommand({ createIndexes : « collectionName », index : [{ {"index_spec"}], enableLargeIndexKeys : true }) ;
Indexation de tableaux imbriqués
Azure DocumentDB permet d’indexer des tableaux imbriqués. L’exemple crée un index sur le resolutions champ existant dans le complains tableau.
CarData> db.sampleColl.createIndex({"rental_history.complains.resolutions":1})
Nous passons en revue le plan avec explain pour identifier toutes les locations, sans fournir de résolution au client.
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
}
Indexation d’un champ spécifique dans un tableau
Azure DocumentDB permet l’indexation de champs dans un tableau. L’exemple crée un index dans le champ date à l'intérieur du tableau accidents.
CarData> db.sampleColl.createIndex({"rental_history.accidents.date":1})
L’exemple de requête évalue les accidents entre un intervalle de temps, affiche l’index créé sur la date propriété utilisée.
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
}
Note
Nous améliorons actuellement la prise en charge des tableaux imbriqués. Dans certains cas de périphérie, des opérations d’indexation spécifiques peuvent entraîner des erreurs.
Indexation par caractères génériques tout en excluant les champs imbriqués
Azure DocumentDB prend en charge les index génériques. L’exemple nous permet d’exclure l’indexation de tous les champs imbriqués dans le document 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
}
}
)
Le plan d’exécution n’affiche aucune prise en charge des requêtes effectuées sur le champ model, qui a été exclu lors de la création de l’index avec caractères génériques.
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
}
Indexation avec caractères génériques lors de l’exclusion des objets imbriqués
Azure DocumentDB prend en charge les index génériques. L’exemple nous permet d’exclure les objets imbriqués du document.
// Wildcard index excluding nested object
[mongos] CarData> db.sampleColl.createIndex( {"$**":1},
{"wildcardProjection":
{ "car_info":0
,"rental_history":0
}
}
)
Le plan d’exécution n’affiche aucune prise en charge des requêtes effectuées sur un champ make imbriqué dans le car_info document.
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
}
Indexation par caractères génériques tout en excluant les champs contenant un tableau imbriqué
L’exemple d’index générique permet d’exclure les champs du tableau imbriqué. Nous utilisons la collection pokemon avec le format json mis en surbrillance.
{
{
"_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" }]
}
}
Nous créons un index sur tous les champs au sein du JSON, à l’exception des champs num et name d’un tableau.
Cosmicworks> db.Pokemon.createIndex( {"$**":1},
{"wildcardProjection":
{ "id":0
,"name":0
,"multipliers":0
,"next_evolution.num":0
,"next_evolution.name":0
}
}
)
Le plan d’explication n’affiche aucune utilisation de l’index lors de l’interrogation sur le champ name dans le tableau 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
}
Étapes suivantes
- Découvrez ici l’indexation par caractères génériques.
- Découvrez les meilleures pratiques d’indexation pour les résultats les plus efficaces.
- En savoir plus sur l’indexation en arrière-plan
- Apprenez ici à utiliser l’indexation de texte.