

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

# Interrogation dans Amazon DocumentDB
<a name="querying"></a>

Cette section explique tous les aspects des requêtes avec Amazon DocumentDB.

**Topics**
+ [Interrogation de documents](#querying.docs)
+ [Plan de requête](#querying.queryplan)
+ [Expliquer les résultats](#querying.explainresults)
+ [Planificateur de requêtes v2](query-planner.md)
+ [Planificateur de requêtes v3](query-planner-v3.md)
+ [Données géospatiales](geospatial.md)
+ [Index partiel](partial-index.md)
+ [Recherche de texte](text-search.md)

## Interrogation de documents
<a name="querying.docs"></a>

Il arrive que vous ayez besoin de consulter le stock de votre boutique en ligne, pour que les clients puissent voir et acheter ce que vous vendez. Interroger une collection est relativement simple, qu'il s'agisse de tous les documents dans la collection ou uniquement ceux qui répondent à un critère particulier.

Pour interroger des documents, utilisez l'opération `find()`. La commande `find()` possède un seul paramètre de document qui définit les critères à utiliser pour choisir le documents à renvoyer Le résultat obtenu à partir de `find()` est d'un document formaté en une seule ligne de texte sans sauts de ligne. Pour formater le document de sortie afin d'en faciliter la lecture, utilisez `find().pretty()`. Tous les exemples de cette rubrique utilisent `.pretty()` pour mettre en forme les données de sortie.

Les exemples de code suivants utilisent les quatre documents que vous avez insérés dans la `example` collection au cours des deux exercices précédents `insertOne()` et `insertMany()` qui se trouvent dans la section Ajouter des documents de la section [Travailler avec des documents](https://docs.aws.amazon.com//documentdb/latest/developerguide/document-database-working-with-documents.html).

**Topics**
+ [Récupération de tous les documents](#querying.alldocs)
+ [Valeurs de champ correspondantes](#querying.matchfield)
+ [Documents intégrés](#querying.embedded-doc)
+ [Valeurs de champ dans les documents incorporés](#querying.embedded-docs-field)
+ [Correspondance à un tableau](#querying.array)
+ [Correspondance de valeurs dans un tableau](#querying.array-values)
+ [Utilisation d'opérateurs](#querying.operators)

### Récupération de tous les documents d'une collection
<a name="querying.alldocs"></a>

Pour récupérer tous les documents de votre collection, utilisez l'opération `find()` avec un document de requête vide.

La requête suivante renvoie tous les documents de la collection `example`.

```
db.example.find( {} ).pretty()
```

### Récupération de documents correspondant à une valeur de champ
<a name="querying.matchfield"></a>

Pour récupérer tous les documents qui correspondent à un champ et à une valeur, utilisez l'opération `find()` avec un document de requête qui identifie les champs et les valeurs à faire correspondre.

En utilisant les documents précédents, cette requête renvoie tous les documents où le champ « Item (Élément) » est défini sur « Pen ».

```
db.example.find( { "Item": "Pen" } ).pretty()
```

### Récupération de documents correspondant à un document intégré
<a name="querying.embedded-doc"></a>

Pour rechercher tous les documents qui correspondent à un document intégré, utilisez l'opération `find()` avec un document de requête qui spécifie le nom du document intégré et tous les champs et les valeurs de ce document intégré.

Lorsqu'une correspondance est établie avec un document intégré , le nom de ce document doit être identique à celui spécifié dans la requête. De plus, les champs et les valeurs dans le document intégré doivent correspondre à la requête.

La requête suivante renvoie uniquement le document « Poster Paint ». Cela est dû au fait que « Pen » a des valeurs différentes pour « `OnHand` » et « `MinOnHand` », et que et « Spray Paint » a un champ de plus (`OrderQnty`) que le document de requête.

```
db.example.find({"Inventory": {
    "OnHand": 47,
    "MinOnHand": 50 } } ).pretty()
```

### Extraction de documents qui correspondent à une valeur de champ dans un document intégré
<a name="querying.embedded-docs-field"></a>

Pour rechercher tous les documents qui correspondent à un document intégré, utilisez l'opération `find()` avec un document de requête qui spécifie le nom du document intégré et tous les champs et les valeurs de ce document intégré.

Au vu des documents précédents, la requête suivante utilise la « notation de points » pour spécifier le document intégré et les champs d'intérêt. Tout document correspondant est renvoyé, quels que soient les autres champs présents dans le document intégré. La requête renvoie « Poster Paint » et « Spray Paint », car ils correspondent tous deux aux champs et aux valeurs spécifiés.

```
db.example.find({"Inventory.OnHand": 47, "Inventory.MinOnHand": 50 }).pretty()
```

### Récupération de documents correspondant à un tableau
<a name="querying.array"></a>

Pour rechercher tous les documents qui correspondent à un tableau, utilisez l'opération `find()` avec le nom du tableau qui vous intéresse et toutes les valeurs de ce tableau. La requête renvoie tous les documents ayant un tableau avec ce nom et dans lequel les valeurs sont identiques et figurent dans le même ordre que dans la requête.

La requête suivante renvoie uniquement « Pen », car « Poster Paint » a une couleur supplémentaire (blanc) et les couleurs de « Spray Paint » figurent dans un ordre différent.

```
db.example.find( { "Colors": ["Red","Green","Blue","Black"] } ).pretty() 
```

### Récupération de documents correspondant à une valeur d'un tableau
<a name="querying.array-values"></a>

Pour rechercher tous les documents contenant une valeur de tableau particulière, utilisez l'opération `find()` avec le nom du tableau et la valeur qui vous intéressent.

```
db.example.find( { "Colors": "Red" } ).pretty() 
```

L'opération précédente renvoie les trois documents, car chacun d'entre eux possède un tableau nommé `Colors` et la valeur « `Red` » dans le tableau. Si vous spécifiez la valeur « `White` », la requête renvoie uniquement « Poster Paint ».

### Récupération de documents à l'aide d'opérateurs
<a name="querying.operators"></a>

La requête suivante renvoie tous les documents où la valeur « `Inventory.OnHand` » est inférieure à 50.

```
db.example.find(
        { "Inventory.OnHand": { $lt: 50 } } )
```

Pour obtenir une liste des opérateurs de requête pris en charge, consultez [Opérateurs de requête et de projection](mongo-apis.md#mongo-apis-query). 

## Plan de requête
<a name="querying.queryplan"></a>

### Comment puis-je voir `executionStats` pour un plan de requête ?
<a name="querying.queryplan-executionStats"></a>

Lorsque vous déterminez pourquoi une requête s'exécute plus lentement que prévu, il peut être utile de comprendre ce que représente `executionStats` pour le plan de requête. `executionStats` fournit le nombre de documents renvoyés à partir d'une étape particulière (`nReturned`), le temps d'exécution passé à chaque étape (`executionTimeMillisEstimate`) et le temps nécessaire à la génération d’un plan de requête (`planningTimeMillis`). Vous pouvez déterminer les étapes les plus longues de votre requête pour vous aider à concentrer vos efforts d'optimisation à partir de la sortie de `executionStats`, comme illustré dans les exemples de requête ci-dessous. Le paramètre `executionStats` ne prend pas actuellement en charge les commandes `update` et `delete`.

**Note**  
Amazon DocumentDB émule l'API MongoDB 3.6 sur un moteur de base de données spécialement conçu qui utilise un système de stockage distribué, tolérant aux pannes et autoréparateur. Par conséquent, les plans de requête et le résultat de `explain()` peuvent différer entre Amazon DocumentDB et MongoDB. Les clients qui souhaitent contrôler leur plan de requête peuvent utiliser l'opérateur `$hint` pour appliquer la sélection d'un index préféré.

Exécutez la requête que vous souhaitez améliorer sous la commande `explain()` comme suit.

```
db.runCommand({explain: {query document}}).
explain("executionStats").executionStats;
```

Voici un exemple d'opération.

```
db.fish.find({}).limit(2).explain("executionStats");
```

Le résultat de cette opération ressemble à ceci.

```
{
    "queryPlanner" : {
        "plannerVersion" : 1,
        "namespace" : "test.fish",
        "winningPlan" : {
            "stage" : "SUBSCAN",
            "inputStage" : {
                "stage" : "LIMIT_SKIP",
                "inputStage" : {
                    "stage" : "COLLSCAN"
                }
            }
        }
    },
    "executionStats" : {
        "executionSuccess" : true,
        "executionTimeMillis" : "0.063",
        "planningTimeMillis" : "0.040",
        "executionStages" : {
            "stage" : "SUBSCAN",
            "nReturned" : "2",
            "executionTimeMillisEstimate" : "0.012",
            "inputStage" : {
                "stage" : "LIMIT_SKIP",
                "nReturned" : "2",
                "executionTimeMillisEstimate" : "0.005",
                "inputStage" : {
                    "stage" : "COLLSCAN",
                    "nReturned" : "2",
                    "executionTimeMillisEstimate" : "0.005"
                }
            }
        }
    },
    "serverInfo" : {
        "host" : "enginedemo",
        "port" : 27017,
        "version" : "3.6.0"
    },
    "ok" : 1
}
```

Si vous êtes intéressé uniquement par les informations relatives à `executionStats` de la requête ci-dessus, vous pouvez utiliser la commande suivante. Pour les petites collections, le processeur de requêtes Amazon DocumentDB peut choisir de ne pas utiliser d'index si les gains de performances sont négligeables.

```
db.fish.find({}).limit(2).explain("executionStats").executionStats;
```

### Cache du plan de requêtes
<a name="querying.queryplan-cached"></a>

Afin d'optimiser les performances et de réduire la durée de planification, Amazon DocumentDB met en cache les plans de requêtes en interne. Cela permet d'exécuter des requêtes de même forme directement à l'aide d'un plan mis en cache.

Cependant, cette mise en cache peut parfois entraîner un retard aléatoire pour la même requête ; par exemple, une requête dont l'exécution prend généralement une seconde peut parfois prendre dix secondes. En effet, au fil du temps, l'instance du lecteur a mis en cache différentes formes de la requête, consommant ainsi de la mémoire. Si vous rencontrez cette lenteur aléatoire, aucune action n'est nécessaire pour libérer la mémoire : le système gérera l'utilisation de la mémoire à votre place et une fois que la mémoire aura atteint un certain seuil, elle sera automatiquement libérée.

## Expliquer les résultats
<a name="querying.explainresults"></a>

Si vous souhaitez renvoyer des informations sur les plans de requête, Amazon DocumentDB prend en charge le mode verbosité. `queryPlanner` Les `explain` résultats renvoient le plan de requête sélectionné par l'optimiseur dans un format similaire au suivant :

```
{
   "queryPlanner" : {
      "plannerVersion" : <int>,
      "namespace" : <string>,
      "winningPlan" : {
         "stage" : <STAGE1>,
         ...
         "inputStage" : {
            "stage" : <STAGE2>,
            ...
            "inputStage" : {
               ...
            }
         }
      }
   }
}
```

Les sections suivantes définiront les `explain` résultats communs.

**Topics**
+ [Étape de numérisation et de filtrage](#querying.explainresults-scan-filter)
+ [Intersection de l'index](#querying.explainresults-index-intersection)
+ [Union indicielle](#querying.explainresults-index-union)
+ [Intersection/union à indices multiples](#querying.explainresults-multiple-index-union)
+ [Indice composé](#querying.explainresults-compound-index)
+ [Étape de tri](#querying.explainresults-sort)
+ [Phase de groupes](#querying.explainresults-group)

### Étape de numérisation et de filtrage
<a name="querying.explainresults-scan-filter"></a>

L'optimiseur peut choisir l'un des scans suivants :

COLLISCAN

Cette étape est une analyse de collecte séquentielle.

```
{
    "stage" : "COLLSCAN"
}
```

IXSCAN

Cette étape analyse les clés d'index. L'optimiseur peut récupérer le document au cours de cette étape, ce qui peut entraîner l'ajout d'une étape FETCH ultérieurement.

```
db.foo.find({"a": 1})
{
    "stage" : "IXSCAN",
    "direction" : "forward",
    "indexName" : <idx_name>
}
```

FETCH

Si l'optimiseur a extrait des documents dans une étape autre que IXSCAN, le résultat inclura une étape FETCH. Par exemple, la requête IXSCAN ci-dessus peut entraîner une combinaison des étapes FETCH et IXSCAN :

```
db.foo.find({"a": 1})
{
    "stage" : "FETCH",
    "inputStage" : {
        "stage" : "IXSCAN",
        "indexName" : <idx_name>
    }
}
```

IXONLYSCAN analyse uniquement la clé d'index. Créer des index composés n'évitera pas FETCH.

### Intersection de l'index
<a name="querying.explainresults-index-intersection"></a>

MIXEUR

Amazon DocumentDB peut inclure un stage IXAND avec un tableau InputStages d'IXSCAN s'il peut utiliser l'intersection d'index. Par exemple, nous pouvons voir des résultats tels que :

```
{
    "stage" : "FETCH",
    "inputStage" : {
        "stage" : "IXAND",
        "inputStages" : [
            {
                "stage" : "IXSCAN",
                "indexName" : "a_1"
            },
            {
                "stage" : "IXSCAN",
                "indexName" : "b_1"
            }
        ]
    }
}
```

### Union indicielle
<a name="querying.explainresults-index-union"></a>

IXOR

Comme pour l'intersection d'index, Amazon DocumentDB peut inclure un `IXOR` stage avec un `inputStages` tableau pour l'`$or`opérateur.

```
db.foo.find({"$or": [{"a": {"$gt": 2}}, {"b": {"$lt": 2}}]})
```

Pour la requête ci-dessus, la sortie d'explication peut ressembler à ceci :

```
{
    "stage" : "FETCH",
    "inputStage" : {
        "stage" : "IXOR",
        "inputStages" : [
            {
                "stage" : "IXSCAN",
                "indexName" : "a_1"
            },
            {
                "stage" : "IXSCAN",
                "indexName" : "b_1"
            }
        ]
    }
}
```

### Intersection/union à indices multiples
<a name="querying.explainresults-multiple-index-union"></a>

Amazon DocumentDB peut combiner plusieurs étapes d'intersection ou d'union d'index, puis récupérer le résultat. Par exemple :

```
{
    "stage" : "FETCH",
    "inputStage" : {
        "stage" : "IXOR",
        "inputStages" : [
            {
                "stage" : "IXSCAN",
                ...
            },
            {
                "stage" : "IXAND",
                "inputStages" : [
                    {
                        "stage" : "IXSCAN",
                        ...
                    },
                    {
                        "stage" : "IXSCAN",
                        ...
                    }
                ]
            }
        ]
    }
}
```

L'utilisation des étapes d'intersection ou d'union d'index n'est pas affectée par le type d'indice (épars, composé, etc.).

### Indice composé
<a name="querying.explainresults-compound-index"></a>

L'utilisation de l'index composé Amazon DocumentDB n'est pas limitée dans les premiers sous-ensembles de champs indexés ; elle peut utiliser l'index avec le suffixe, mais cela peut ne pas être très efficace.

Par exemple, l'index composé de `{ a: 1, b: -1 }` peut prendre en charge les trois requêtes ci-dessous :

`db.orders.find( { a: 1 } )`

`db.orders.find( { b: 1 } )`

`db.orders.find( { a: 1, b: 1 } )`

### Étape de tri
<a name="querying.explainresults-sort"></a>

S'il existe un index sur la ou les clés de tri demandées, Amazon DocumentDB peut utiliser cet index pour obtenir la commande. Dans ce cas, le résultat n'inclura pas d'`SORT`étape, mais plutôt une `IXSCAN` étape. Si l'optimiseur privilégie un tri simple, il inclura une étape comme celle-ci :

```
{
    "stage" : "SORT",
    "sortPattern" : {
        "a" : 1,
        "b" : -1
    }
}
```

### Phase de groupes
<a name="querying.explainresults-group"></a>

Amazon DocumentDB prend en charge deux stratégies de groupe différentes :
+ `SORT_AGGREGATE`: agrégat de tri sur disque.
+ `HASH_AGGREGATE`: agrégat de hachage en mémoire.