Combinez deux collections en une seule à l'aide de MongoDB

Mehvish Ashiq 30 janvier 2023
  1. Combinez deux collections en une seule à l’aide de MongoDB
  2. Utilisez l’étape d’agrégation $lookup pour joindre deux collections en une seule
  3. Utilisez l’opérateur pipeline pour joindre deux collections en une seule en fonction de la condition spécifiée
  4. Utilisez l’opérateur $unwind pour créer un tableau plat avant de vous attacher aux documents résultants
  5. Utilisez l’étape de filtre $project dans les requêtes d’agrégation pour joindre deux collections en une seule
  6. Joindre deux collections à l’aide de Compass (interface graphique de MongoDB)
Combinez deux collections en une seule à l'aide 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.

  1. Utilisez l’étape d’agrégation $lookup pour joindre deux collections
  2. Utilisez l’opérateur pipeline pour joindre deux collections en fonction de la condition spécifiée
  3. Utilisez l’opérateur $unwind pour aplatir un tableau avant de l’attacher aux documents résultants
  4. Utilisez l’étape de filtre $project dans les requêtes d’agrégation pour joindre deux collections
  5. 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.

combiner deux collections en une seule en utilisant mongodb - explication de l’étape de recherche

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.

  1. Ouvrez MongoDBCompass et connectez-vous au serveur.

  2. 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.

  3. Ouvrez vos collections qui se présenteront comme suit.

    combiner deux collections en une seule à l’aide de mongodb - collections ouvertes de la boussole

  4. 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.

    combiner deux collections en une seule en utilisant mongodb - boussole ajouter une étape de recherche

Mehvish Ashiq avatar Mehvish Ashiq avatar

Mehvish Ashiq is a former Java Programmer and a Data Science enthusiast who leverages her expertise to help others to learn and grow by creating interesting, useful, and reader-friendly content in Computer Programming, Data Science, and Technology.

LinkedIn GitHub Facebook

Article connexe - MongoDB Collection