HOWTO · MongoDB
Projeter des champs imbriqués dans MongoDB
Découvrez comment sélectionner des champs MongoDB imbriqués avec la notation par points et find(), mettre en forme les résultats d’agrégation avec $project et supprimer des champs avec l’étape d’agrégation $unset.
Sur cette page
Les documents MongoDB peuvent contenir des documents imbriqués, par exemple un objet address dans un document utilisateur. Une projection détermine les champs renvoyés par une requête. Par exemple, sélectionner address.city renvoie cette valeur imbriquée tout en conservant sa structure. Utilisez une projection find() pour obtenir directement le résultat d’une requête, $project pour mettre en forme les documents dans un pipeline d’agrégation et $unset pour supprimer certains champs des résultats du pipeline.
Comprendre la projection des champs imbriqués dans MongoDB
Supposons qu’un document comporte les champs name et address, et que address contienne street, city et country. Un chemin imbriqué s’écrit avec la notation par points, par exemple address.city. La projection modifie le document renvoyé, mais pas le document source stocké. Les exemples ci-dessous utilisent cette même structure. Dans les projections find(), _id est inclus par défaut, sauf si vous l’excluez explicitement.
Utiliser la notation par points avec find() pour sélectionner des champs imbriqués
Pour ne renvoyer que la ville de l’adresse imbriquée, incluez son chemin avec la notation par points. Cette expression de shell MongoDB illustre la syntaxe et n’est pas exécutée par l’environnement d’exécution configuré :
db.users.find({}, { "address.city": 1, "_id": 0 })
Le résultat a la forme suivante : { "address": { "city": "New York" } }. Omettez _id: 0 si vous souhaitez conserver l’identifiant dans chaque résultat. Pour exclure un chemin imbriqué tout en gardant les autres champs, utilisez 0, comme dans { "address.country": 0 }.
En règle générale, une projection par inclusion ne peut pas mélanger champs inclus et exclus. L’exception concerne _id : vous pouvez l’exclure tout en incluant d’autres chemins. Pour les autres champs, choisissez une projection par inclusion ou par exclusion.
Exécutez cet exemple. Le code et sa sortie restent en anglais pour préserver l’exemple d’origine; la sortie illustre la structure imbriquée renvoyée :
document = {"name": "Ava", "address": {"city": "New York", "country": "USA"}}
result = {"address": {"city": document["address"]["city"]}}
print(result)
{'address': {'city': 'New York'}}
Ce petit exemple Python illustre la structure imbriquée renvoyée; il ne se connecte pas à MongoDB. La requête MongoDB ci-dessus utilise le chemin correspondant indiqué avec la notation par points.
Utiliser l’étape d’agrégation $project pour mettre en forme les champs imbriqués
Dans un pipeline d’agrégation, $project peut inclure des chemins imbriqués et faire correspondre des chemins source à des champs de sortie. Par exemple, { $project: { _id: 0, city: "$address.city", name: 1 } } renvoie city au niveau supérieur, à côté de name. Une inclusion directe d’un chemin, telle que { $project: { "address.city": 1, _id: 0 } }, conserve au contraire l’imbrication address.city. $project est donc utile lorsque le pipeline doit produire une structure de sortie précise. Les expressions peuvent aussi calculer des valeurs de sortie; veillez à ce que chacune fasse référence à un champ présent dans les documents d’entrée.
Utiliser l’étape d’agrégation $unset pour exclure des champs imbriqués
Utilisez l’étape d’agrégation $unset pour supprimer un ou plusieurs chemins tout en conservant les autres champs : { $unset: ["address.country"] }. Un chemin avec la notation par points supprime ce champ imbriqué du résultat du pipeline. $unset détermine quels champs poursuivent leur parcours dans le pipeline; cette étape ne filtre pas les documents. Pour filtrer les documents, utilisez une condition de requête ou l’étape $match. Cette étape d’agrégation est distincte de l’opérateur de mise à jour qui porte le même nom.
Choisir entre projection de requête et agrégation
Utilisez find() avec la notation par points lorsqu’une requête doit simplement inclure ou exclure des champs dans les documents renvoyés. Choisissez $project lorsqu’une agrégation doit renommer des chemins, calculer des valeurs ou définir une structure de sortie précise. Choisissez $unset lorsque le pipeline doit conserver la plupart des champs et en supprimer quelques-uns. $addFields ajoute ou remplace des champs tout en conservant le reste du document; il ne remplace donc pas une projection destinée à sélectionner des champs. Dans les trois cas, la projection ou la mise en forme des champs agit sur les résultats, et non sur les documents stockés.