MongoDB est une base de données NoSQL populaire qui stocke les données dans des collections. Les collections MongoDB sont composées d’un ou plusieurs documents qui contiennent les données réelles au format JSON. Les documents sont comparables aux lignes des bases de données relationnelles SQL traditionnelles, tandis que les collections sont analogues aux tables.
L’une des principales fonctionnalités des bases de données est la possibilité d’interroger les données qui y sont stockées. L’interrogation des données permet de récupérer des informations spécifiques, d’analyser les données, d’établir des rapports sur les données et d’intégrer les données.
Pour pouvoir interroger efficacement une base de données, il est essentiel de pouvoir combiner des données provenant de plusieurs tables, dans le cas des bases de données SQL, ou de plusieurs collections dans le cas des bases de données NOSQL, en un seul ensemble de résultats.
Dans MongoDB, $lookup permet aux utilisateurs de combiner des informations provenant de deux collections lors de l’interrogation. Il effectue l’équivalent d’une jointure externe gauche dans une base de données SQL.
utilisation et objectif de $lookup
Une fonction importante des bases de données est le traitement des données afin d’obtenir des informations significatives à partir de données brutes.
Par exemple, si vous gérez un restaurant, vous voudrez peut-être analyser les données de votre restaurant pour savoir combien vous gagnez chaque jour, quels sont les plats les plus demandés le week-end ou même combien de tasses de café vous vendez à chaque heure de la journée.
Pour de tels besoins, de simples requêtes dans la base de données ne suffisent pas. Vous devez effectuer des requêtes avancées sur les données que vous avez stockées. Pour répondre à ces besoins, MongoDB dispose d’une fonctionnalité appelée pipeline d’agrégation.
Un pipeline d’agrégation est un système composé d’opérations composables appelées étapes, qui sont utilisées pour traiter les données afin de produire un résultat agrégé final. Parmi les exemples d’étapes du pipeline d’agrégation, citons $sort, $match, $group, $merge, $count et $lookup, entre autres.
Ces étapes peuvent être appliquées dans n’importe quel ordre dans un pipeline d’agrégation. À chaque étape d’un pipeline d’agrégation, différentes opérations sont effectuées sur les données qui passent par le pipeline d’agrégation.
$lookup est donc une étape du pipeline d’agrégation de MongoDB. $Lookup est utilisé pour effectuer une jointure externe gauche entre deux collections dans une base de données MongoDB. Une jointure externe gauche combine tous les documents ou entrées de gauche avec les documents ou entrées correspondants de droite.
Par exemple, considérez les deux collections ci-dessous, qui ont été représentées sous forme de tableau pour une meilleure compréhension :
collection_commandes:
order_id | identifiant_client | date_de_la_commande | montant total |
---|---|---|---|
1 | 100 | 2022-05-01 | 50.00 |
2 | 101 | 2022-05-02 | 75.00 |
3 | 102 | 2022-05-03 | 100.00 |
collection_clients:
numéro_client | nom_client | e-mail_client | téléphone_client |
---|---|---|---|
100 | Monsieur Untel | john@example.com | 555-1234 |
102 | Jane Smith | jane@example.com | 555-5678 |
Si nous effectuons une jointure externe gauche sur les collections ci-dessus en utilisant le champ customer_id, qui apparaît dans la collection order_collection, la collection order_collection étant la collection de gauche et la collection customers_collection étant la collection de droite, le résultat contiendra tous les documents de la collection Orders et les documents de la collection Customers dont le numéro de client correspond à un numéro de client de l’un des enregistrements de la collection Orders.
Le résultat final de l’opération de jointure externe gauche sur les collections commandes et clients ressemble à ceci lorsqu’il est représenté sous forme de tableau :
Remarquez que pour le client avec le numéro de client 101 dans le recueil des commandes, qui n’a pas de valeur de numéro de client correspondante dans le recueil des clients, les valeurs correspondantes manquantes de la table des clients ont été remplies avec null.
$lookup effectue une comparaison d’égalité stricte entre les champs et récupère l’ensemble du document correspondant, et pas seulement les champs correspondants.
syntaxe de $lookup
La syntaxe de $lookup est la suivante :
{
$lookup :
{
from : <collection à joindre>,
localField : <champ des documents d'entrée>,
foreignField : <champ des documents de la collection "from">,
as : <champ du tableau de sortie>
}
}
$lookup a quatre paramètres :
- from – représente la collection à partir de laquelle nous voulons consulter les documents. Dans notre exemple précédent utilisant orders_collection et customers_collection, nous avons mis customers_collection comme from de la collection.
- localField – il s’agit d’un champ de la collection de travail ou de la collection primaire que nous utilisons pour comparer les champs de notre collection de départ(collection_clients dans notre cas). Dans l’exemple ci-dessus, le champ local serait customer_id qui se trouve dans la collection orders_collection.
- foreignField – il s’agit du champ auquel nous voulons nous comparer dans la collection que nous spécifions dans from. Dans notre exemple, il s’agit de customer_num qui se trouve dans le recueil customer_collection et que nous utilisons comme valeur dans from
- as – il s’agit d’un nouveau nom de champ que nous spécifions pour représenter le champ qui apparaîtra dans notre document, qui contient les documents résultant des correspondances entre le champ local (localField) et le champ étranger (foreignField). Toutes ces correspondances sont placées dans un tableau dans ce champ. S’il n’y a pas de correspondance, ce champ contiendra un tableau vide.
À partir de nos deux collections précédentes, nous utiliserions le code suivant pour effectuer une opération $lookup sur les deux collections avec la collection orders_ comme collection de travail ou collection primaire.
{
$lookup : {
from : "customers_collection",
localField : "customer_id",
foreignField : "customer_num",
as : "customer_info"
}
Notez que le champ as peut contenir n’importe quelle chaîne de caractères. Toutefois, si vous lui donnez un nom qui existe déjà dans le document de travail, ce champ sera remplacé.
Joindre des données provenant de plusieurs collections
MongoDB $lookup est une étape utile dans un pipeline d’agrégation dans MongoDB. Bien qu’il ne soit pas obligatoire qu’un pipeline d’agrégation dans MongoDB ait une étape $lookup , cette étape est cruciale lors de l’exécution de requêtes complexes qui nécessitent de joindre des données provenant de plusieurs collections.
L’étape $lookup effectue une jointure externe gauche sur deux collections, ce qui entraîne la création d’un nouveau champ ou l’écrasement des valeurs d’un champ existant par un tableau contenant des documents provenant d’une autre collection.
Ces documents sont sélectionnés en fonction de la correspondance de leurs valeurs avec celles du champ auquel ils sont comparés. Le résultat final est un champ contenant un tableau de documents si des correspondances ont été trouvées ou un tableau vide si aucune correspondance n’a été trouvée.
Prenons l’exemple des collections d’employés et de projets présentées ci-dessous.
Nous pouvons utiliser le code suivant pour joindre les deux collections :
db.projects.aggregate([
{
$lookup : {
from : "employees",
localField : "employees",
foreignField : "_id",
as : "assigned_employees"
}
}
])
Le résultat de cette opération est une combinaison des deux collections. Il s’agit des projets et de tous les employés affectés à chaque projet. Les employés sont représentés dans un tableau.
Étapes du pipeline pouvant être utilisées avec $lookup
Comme indiqué précédemment, $lookup est une étape d’un pipeline d’agrégation MongoDB, et il peut être utilisé avec d’autres étapes du pipeline d’agrégation. Pour montrer comment ces étapes peuvent être utilisées avec $lookup, nous utiliserons les deux collections suivantes à des fins d’illustration.
Dans MongoDB, elles sont stockées au format JSON. Voici à quoi ressemblent les collections ci-dessus dans MongoDB.
Voici quelques exemples d’étapes du pipeline d’agrégation qui peuvent être utilisées avec $lookup:
$match
$match est une étape du pipeline d’agrégation utilisée pour filtrer le flux de documents afin de n’autoriser que les documents qui répondent à une condition donnée à passer à l’étape suivante du pipeline d’agrégation. Il est préférable d’utiliser cette étape au début du pipeline afin de supprimer les documents qui ne seront pas nécessaires et d’optimiser ainsi le pipeline d’agrégation.
En utilisant les deux collections précédentes, vous pouvez combiner $match et $lookup comme suit :
db.users.aggregate([
{
$match : {
pays : "USA"
}
},
{
$lookup : {
from : "orders",
localField : "_id",
foreignField : "user_id",
as : "orders"
}
}
])
$match est utilisé pour filtrer les utilisateurs des États-Unis. Le résultat de $match est ensuite combiné avec $lookup pour obtenir les détails des commandes des utilisateurs des États-Unis. Le résultat de l’opération ci-dessus est illustré ci-dessous :
$projet
$project est une étape utilisée pour remodeler les documents en spécifiant les champs à inclure, à exclure ou à ajouter aux documents. Par exemple, si vous traitez des documents comportant dix champs chacun, mais que seuls quatre champs des documents contiennent des données dont vous avez besoin pour votre traitement de données, vous pouvez utiliser $project pour filtrer les champs dont vous n’avez pas besoin.
Cela vous permet d’éviter d’envoyer des données inutiles à l’étape suivante de votre pipeline d’agrégation.
Nous pouvons combiner $lookup et $project de la manière suivante :
db.users.aggregate([
{
$lookup : {
from : "orders",
localField : "_id",
foreignField : "user_id",
as : "orders"
}
},
{
$project : {
name : 1,
_id : 0,
total_spent : { $sum : "$orders.price" }
}
}
])
Ce qui précède combine les collections d’utilisateurs et de commandes à l’aide de $lookup, puis $project est utilisé pour afficher uniquement le nom de chaque utilisateur et le montant dépensé par chacun d’entre eux. $project est également utilisé pour supprimer le champ _id des résultats. Le résultat de l’opération ci-dessus est illustré ci-dessous :
$unwind
$unwind est une étape d’agrégation utilisée pour déconstruire ou dérouler un champ de tableau en créant de nouveaux documents pour chaque élément du tableau. Cette étape est utile lorsque vous souhaitez effectuer des agrégations sur les valeurs des champs du tableau.
Par exemple, dans l’exemple ci-dessous, si vous souhaitez effectuer une agrégation sur le champ hobbies, vous ne pouvez pas le faire car il s’agit d’un tableau. Cependant, vous pouvez le dérouler en utilisant $unwind et ensuite effectuer des agrégations sur les documents résultants.
En utilisant les collections users et orders, nous pouvons utiliser $lookup et $unwind ensemble comme suit :
db.users.aggregate([
{
$lookup : {
from : "orders",
localField : "_id",
foreignField : "user_id",
as : "orders"
}
},
{
$unwind : "$orders"
}
])
Dans le code ci-dessus, $lookup renvoie un champ de type tableau appelé orders. $unwind est ensuite utilisé pour dérouler le champ du tableau. Le résultat de cette opération est illustré ci-dessous : Remarquez qu’Alice apparaît deux fois parce qu’elle a passé deux commandes.
Exemples de cas d’utilisation de $lookup
Lors du traitement des données, $lookup est un outil utile. Par exemple, vous pouvez avoir deux collections que vous voulez joindre en vous basant sur les champs des collections qui ont des données similaires. Une simple étape $lookup peut être utilisée pour ce faire et ajouter un nouveau champ dans les collections primaires, qui contiennent des documents obtenus à partir d’une autre collection.
Prenons l’exemple des collections “users” et “orders” présentées ci-dessous :
Les deux collections peuvent être combinées à l’aide de $lookup pour obtenir le résultat ci-dessous :
$lookup peut également être utilisé pour effectuer des jointures plus complexes. l’utilisation de $lookup ne se limite pas à la réalisation de jointures sur deux collections. Vous pouvez mettre en œuvre plusieurs étapes $lookup pour effectuer des jointures sur plus de deux collections. Prenons l’exemple des trois collections présentées ci-dessous :
Nous pouvons utiliser le code ci-dessous pour effectuer une jointure plus complexe sur les trois collections afin d’obtenir toutes les commandes effectuées ainsi que les détails des produits commandés.
Le code ci-dessous nous permet d’effectuer cette opération :
db.orders.aggregate([
{
$lookup : {
from : "order_items",
localField : "_id",
foreignField : "order_id",
as : "order_items"
}
},
{
$unwind : "$order_items"
},
{
$lookup : {
from : "products",
localField : "order_items.product_id",
foreignField : "_id",
as : "product_details"
}
},
{
$group : {
_id : "$_id",
client : { $first : "$customer" },
total : { $sum : "$order_items.price" },
produits : { $push : "$product_details" }
}
}
])
Le résultat de l’opération ci-dessus est illustré ci-dessous :
Conclusion
Lorsque vous effectuez un traitement de données impliquant plusieurs collections, $lookup peut être utile car il vous permet de joindre des données et de tirer des conclusions basées sur des données stockées dans plusieurs collections. Le traitement des données repose rarement sur une seule collection.
Pour tirer des conclusions significatives à partir des données, la jonction des données entre plusieurs collections est une étape clé. Par conséquent, envisagez d’utiliser l’étape $lookup dans votre pipeline d’agrégation MongoDB pour vous permettre de mieux traiter vos données et de tirer des conclusions significatives des données brutes stockées dans plusieurs collections.
Vous pouvez également explorer certaines commandes et requêtes MongoDB.