Combinez deux collections en une seule à l'aide de MongoDB
- Combinez deux collections en une seule à l’aide de MongoDB
-
Utilisez l’étape d’agrégation
$lookup
pour joindre deux collections en une seule -
Utilisez l’opérateur
pipeline
pour joindre deux collections en une seule en fonction de la condition spécifiée -
Utilisez l’opérateur
$unwind
pour créer un tableau plat avant de vous attacher aux documents résultants -
Utilisez l’étape de filtre
$project
dans les requêtes d’agrégation pour joindre deux collections en une seule - Joindre deux collections à l’aide de Compass (interface graphique de MongoDB)
Aujourd’hui, nous allons utiliser l’étape d’agrégation $lookup
, les opérateurs pipeline
et $unwind
, l’étape de filtrage $project
et MongoDB Compass pour combiner deux collections en une seule.
Combinez deux collections en une seule à l’aide de MongoDB
Nous avons différentes approches pour combiner deux collections en une seule collection à l’aide de MongoDB. Certains d’entre eux sont donnés ci-dessous, que nous aborderons dans ce tutoriel.
- Utilisez l’étape d’agrégation
$lookup
pour joindre deux collections - Utilisez l’opérateur
pipeline
pour joindre deux collections en fonction de la condition spécifiée - Utilisez l’opérateur
$unwind
pour aplatir un tableau avant de l’attacher aux documents résultants - Utilisez l’étape de filtre
$project
dans les requêtes d’agrégation pour joindre deux collections - Joindre deux collections à l’aide d’une boussole (une interface graphique de MongoDB)
Pour tous les scénarios ci-dessus, nous devons avoir une base de données contenant deux collections (identiques aux tables dans MySQL) remplies de documents (identiques aux enregistrements dans MySQL). Nous l’avons fait en utilisant les requêtes suivantes ; vous pouvez le faire aussi.
Créez deux collections nommées usersInformation
et userAddress
qui résident dans la base de données users
. De plus, remplissez-les avec des documents comme suit.
Créer une base de données et des collections :
> use users
> db.createCollection('userInformation')
> db.createCollection('userAddress')
Remplissez la collection userInformation
avec deux documents :
> db.userInformation.insertMany(
[
{
fullname: 'Mehvish Ashiq',
age: 30,
gender: 'Female',
nationality: 'Pakistani'
},
{
fullname: 'James Daniel',
age: 45,
sex: 'male',
nationality: 'Canadian'
}
]
)
Remplissez la collection userAddress
avec deux documents :
> db.userAddress.insertMany(
[
{
fullname: 'Mehvish Ashiq',
block_number: 22,
street: 'Johar Town Street',
city: 'Lahore'
},
{
fullname: 'James Daniel',
block_number: 30,
street: 'Saint-Denis Street',
city: 'Montreal'
}
]
)
Nous utilisons la fonction insertMany()
pour insérer plusieurs documents. Maintenant, nous pouvons utiliser les commandes ci-dessous pour voir les données des deux collections.
Dans l’extrait de code suivant, la méthode pretty()
affiche la sortie propre et formatée, ce qui est facile à comprendre sur le shell.
Afficher les documents de la userInformation
:
> db.userInformation.find().pretty()
PRODUCTION:
{
"_id" : ObjectId("628bc4a45c544feccff5a566"),
"fullname" : "Mehvish Ashiq",
"age" : 30,
"gender" : "Female",
"nationality" : "Pakistani"
}
{
"_id" : ObjectId("628bc4a45c544feccff5a567"),
"fullname" : "James Daniel",
"age" : 45,
"sex" : "male",
"nationality" : "Canadian"
}
Afficher les documents de la userAddress
:
> db.userAddress.find().pretty()
PRODUCTION:
{
"_id" : ObjectId("628bc4ae5c544feccff5a568"),
"fullname" : "Mehvish Ashiq",
"block_number" : 22,
"street" : "Johar Town Street",
"city" : "Lahore"
}
{
"_id" : ObjectId("628bc4ae5c544feccff5a569"),
"fullname" : "James Daniel",
"block_number" : 30,
"street" : "Saint-Denis Street",
"city" : "Montreal"
}
Les deux collections doivent se trouver dans la même base de données pour utiliser l’étape d’agrégation $lookup
. Une fois que les deux collections sont prêtes, nous pouvons utiliser les différentes requêtes pour joindre les données des deux collections en fonction du scénario que nous avons.
Utilisez l’étape d’agrégation $lookup
pour joindre deux collections en une seule
Exemple de code :
> db.userInformation.aggregate([
{ $lookup:
{
from: 'userAddress',
localField: 'fullname',
foreignField: 'fullname',
as: 'address'
}
}
]).pretty();
PRODUCTION:
{
"_id" : ObjectId("628bc4a45c544feccff5a566"),
"fullname" : "Mehvish Ashiq",
"age" : 30,
"gender" : "Female",
"nationality" : "Pakistani",
"address" : [
{
"_id" : ObjectId("628bc4ae5c544feccff5a568"),
"fullname" : "Mehvish Ashiq",
"block_number" : 22,
"street" : "Johar Town Street",
"city" : "Lahore"
}
]
}
{
"_id" : ObjectId("628bc4a45c544feccff5a567"),
"fullname" : "James Daniel",
"age" : 45,
"sex" : "male",
"nationality" : "Canadian",
"address" : [
{
"_id" : ObjectId("628bc4ae5c544feccff5a569"),
"fullname" : "James Daniel",
"block_number" : 30,
"street" : "Saint-Denis Street",
"city" : "Montreal"
}
]
}
Dans la base de données MongoDB, le $lookup
étape d’agrégation effectue la jointure externe gauche avec l’autre collection et filtre également les informations (données) des documents joints. Par exemple, nous utilisons la requête pour obtenir toutes les informations des utilisateurs avec leurs adresses.
La fonction $lookup
accepte quatre champs. Le premier est le champ de
, où nous spécifions la collection qui est censée être jointe à l’autre collection.
Le second est le champ localField
. C’est l’un des attributs (champ) des documents d’entrée de la collection spécifié dans le champ from
.
Il est utilisé pour effectuer une correspondance entre le localField
et le foreignField
à partir des documents des collections.
De même, le troisième champ nommé foreignField
effectue également la correspondance d’égalité entre foreignField
et localField
à partir des documents des collections.
Nous écrivons le nom du nouveau tableau pour le quatrième champ, as
. Voir l’explication suivante pour l’étape d’agrégation $lookup
.
Utilisez l’opérateur pipeline
pour joindre deux collections en une seule en fonction de la condition spécifiée
Exemple de code :
> db.userInformation.aggregate([{
$lookup:{
from: 'userAddress',
let: {full_name: '$fullname'},
pipeline: [{
$match: {
$expr: {
$eq: ['$fullname', '$$full_name']
}
}
}],
as: 'addressInfo'
}
}]).pretty()
PRODUCTION:
{
"_id" : ObjectId("628bc4a45c544feccff5a566"),
"fullname" : "Mehvish Ashiq",
"age" : 30,
"gender" : "Female",
"nationality" : "Pakistani",
"addressInfo" : [
{
"_id" : ObjectId("628bc4ae5c544feccff5a568"),
"fullname" : "Mehvish Ashiq",
"block_number" : 22,
"street" : "Johar Town Street",
"city" : "Lahore"
}
]
}
{
"_id" : ObjectId("628bc4a45c544feccff5a567"),
"fullname" : "James Daniel",
"age" : 45,
"sex" : "male",
"nationality" : "Canadian",
"addressInfo" : [
{
"_id" : ObjectId("628bc4ae5c544feccff5a569"),
"fullname" : "James Daniel",
"block_number" : 30,
"street" : "Saint-Denis Street",
"city" : "Montreal"
}
]
}
Nous pouvons utiliser l’opérateur pipeline
avec $lookup
lorsque nous voulons joindre deux collections en fonction d’une condition spécifique (tout comme nous utilisons la clause WHERE
dans MySQL).
Par exemple, nous rejoignons les collections où le fullname
de userAddress
est égal au fullname
dans userInformation
.
Utilisez l’opérateur $unwind
pour créer un tableau plat avant de vous attacher aux documents résultants
Exemple de code :
> db.userInformation.aggregate([
{ $lookup:
{
from: 'userAddress',
localField: 'fullname',
foreignField: 'fullname',
as: 'address'
}
},
{
$unwind: '$address'
}
]).pretty();
PRODUCTION:
{
"_id" : ObjectId("628bc4a45c544feccff5a566"),
"fullname" : "Mehvish Ashiq",
"age" : 30,
"gender" : "Female",
"nationality" : "Pakistani",
"address" : {
"_id" : ObjectId("628bc4ae5c544feccff5a568"),
"fullname" : "Mehvish Ashiq",
"block_number" : 22,
"street" : "Johar Town Street",
"city" : "Lahore"
}
}
{
"_id" : ObjectId("628bc4a45c544feccff5a567"),
"fullname" : "James Daniel",
"age" : 45,
"sex" : "male",
"nationality" : "Canadian",
"address" : {
"_id" : ObjectId("628bc4ae5c544feccff5a569"),
"fullname" : "James Daniel",
"block_number" : 30,
"street" : "Saint-Denis Street",
"city" : "Montreal"
}
}
L’opérateur $unwind
ne fait rien d’autre que d’aplatir le tableau avant de l’attacher au document résultant. La différence fondamentale pour l’opérateur $unwind
est qu’il transforme un tableau avec un seul élément en l’objet aplati, l’élément lui-même.
N’oubliez pas que le nom de cet élément ne sera pas modifié. Ce serait la même chose qu’auparavant lorsque l’élément était sous la forme d’un tableau.
Exécutez la requête ci-dessus avec et sans l’opérateur $unwind
et observez le champ address
.
Utilisez l’étape de filtre $project
dans les requêtes d’agrégation pour joindre deux collections en une seule
Avant de rejoindre les collections en utilisant le $project
, comprenons son importance. Par exemple, si nous ne voulons pas joindre toute la collection nommée userAddress
avec userInformation
, nous voulons que seuls les champs city
et street
soient joints.
Dans ce cas, nous devons utiliser l’étape $addFields
. Nous utilisons cette étape pour joindre/assigner n’importe quel champ ou plusieurs champs d’un tableau/objet au niveau racine du document.
Ainsi, nous exécutons la requête suivante pour récupérer les champs city
et street
de la collection userAddress
.
Exemple de code :
> db.userInformation.aggregate([
{ $lookup:
{
from: 'userAddress',
localField: 'fullname',
foreignField: 'fullname',
as: 'address'
}
},
{
$unwind: '$address'
},
{
$addFields: {
street: '$address.street',
city: '$address.city'
}
}
]).pretty();
PRODUCTION:
{
"_id" : ObjectId("628bc4a45c544feccff5a566"),
"fullname" : "Mehvish Ashiq",
"age" : 30,
"gender" : "Female",
"nationality" : "Pakistani",
"address" : {
"_id" : ObjectId("628bc4ae5c544feccff5a568"),
"fullname" : "Mehvish Ashiq",
"block_number" : 22,
"street" : "Johar Town Street",
"city" : "Lahore"
},
"street" : "Johar Town Street",
"city" : "Lahore"
}
{
"_id" : ObjectId("628bc4a45c544feccff5a567"),
"fullname" : "James Daniel",
"age" : 45,
"sex" : "male",
"nationality" : "Canadian",
"address" : {
"_id" : ObjectId("628bc4ae5c544feccff5a569"),
"fullname" : "James Daniel",
"block_number" : 30,
"street" : "Saint-Denis Street",
"city" : "Montreal"
},
"street" : "Saint-Denis Street",
"city" : "Montreal"
}
Concentrez-vous attentivement sur la sortie donnée ci-dessus. Sommes-nous en train d’obtenir la street
et la city
? Oui, nous obtenons la street
et la city
au niveau racine du document, mais nous avons également l’objet address
dont nous n’avons pas besoin maintenant.
C’est là qu’intervient l’étape du filtre $project
. Il spécifie les champs que nous devrions avoir dans le document résultant.
Voir la requête suivante pour une meilleure compréhension.
Exemple de code :
> db.userInformation.aggregate([
{ $lookup:
{
from: 'userAddress',
localField: 'fullname',
foreignField: 'fullname',
as: 'address'
}
},
{
$unwind: '$address'
},
{
$addFields: {
street: '$address.street',
city: '$address.city'
}
},
{
$project: {
fullname: 1,
age: 1,
gender: 1,
street: 1,
city: 1
}
}
]).pretty();
PRODUCTION:
{
"_id" : ObjectId("628bc4a45c544feccff5a566"),
"fullname" : "Mehvish Ashiq",
"age" : 30,
"gender" : "Female",
"street" : "Johar Town Street",
"city" : "Lahore"
}
{
"_id" : ObjectId("628bc4a45c544feccff5a567"),
"fullname" : "James Daniel",
"age" : 45,
"street" : "Saint-Denis Street",
"city" : "Montreal"
}
Comme vous pouvez le voir, nous n’avons plus l’objet address
maintenant, mais ses deux champs (street
et city
) sont affectés au niveau racine du document.
Joindre deux collections à l’aide de Compass (interface graphique de MongoDB)
L’agrégation à l’aide d’une interface graphique est facile. Il suffit de suivre les étapes suivantes pour l’étape d’agrégation $lookup
.
-
Ouvrez
MongoDBCompass
et connectez-vous au serveur. -
Créez une toute nouvelle base de données et deux collections si vous le souhaitez. Nous utilisons la même base de données et les mêmes collections que nous avons créées à l’aide d’un shell Mongo.
-
Ouvrez vos collections qui se présenteront comme suit.
-
Ajoutez la scène selon les exigences de votre projet ; nous ajoutons l’étape d’agrégation
$lookup
. Mettez à jour les champs$lookup
et voyez les résultats souhaités sur le côté droit.