Combine dos colecciones en una colección usando MongoDB

Mehvish Ashiq 30 enero 2023
  1. Combine dos colecciones en una colección usando MongoDB
  2. Utilice la etapa agregada $lookup para unir dos colecciones en una
  3. Utilice el operador pipeline para unir dos colecciones en una en función de la condición especificada
  4. Use el operador $unwind para la matriz plana antes de adjuntar a los documentos resultantes
  5. Use la etapa de filtro $project en las consultas de agregación para unir dos colecciones en una
  6. Unir dos colecciones usando Compass (interfaz gráfica de MongoDB)
Combine dos colecciones en una colección usando MongoDB

Hoy, utilizaremos la etapa agregada $lookup, los operadores pipeline y $unwind, la etapa de filtro $project y MongoDB Compass para combinar dos colecciones en una colección.

Combine dos colecciones en una colección usando MongoDB

Tenemos diferentes enfoques para combinar dos colecciones en una colección utilizando MongoDB. Algunos de ellos se dan a continuación, que cubriremos en este tutorial.

  1. Use la etapa agregada $lookup para unir dos colecciones
  2. Utilice el operador pipeline para unir dos colecciones en función de la condición especificada
  3. Use el operador $unwind para aplanar una matriz antes de adjuntarla a los documentos resultantes
  4. Use la etapa de filtro $project en las consultas de agregación para unir dos colecciones
  5. Une dos colecciones usando una brújula (una interfaz gráfica de MongoDB)

Para todos los escenarios anteriores, debemos tener una base de datos que contenga dos colecciones (igual que las tablas en MySQL) pobladas con documentos (igual que los registros en MySQL). Lo hemos hecho usando las siguientes consultas; también puedes hacerlo.

Cree dos colecciones denominadas usersInformation y userAddress que residan en la base de datos users. Además, rellénelos con documentos de la siguiente manera.

Crear base de datos y colecciones:

> use users
> db.createCollection('userInformation')
> db.createCollection('userAddress')

Rellene la colección userInformation con dos documentos:

> db.userInformation.insertMany(
    [
        {
            fullname: 'Mehvish Ashiq',
            age: 30,
            gender: 'Female',
            nationality: 'Pakistani'
        },
        {
            fullname: 'James Daniel',
            age: 45,
            sex: 'male',
            nationality: 'Canadian'
        }
    ]
)

Rellene la colección userAddress con dos documentos:

> 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'
        }
    ]
)

Usamos la función insertMany() para insertar múltiples documentos. Ahora, podemos usar los siguientes comandos para ver los datos de ambas colecciones.

En el siguiente fragmento de código, el método pretty() muestra la salida limpia y formateada, que es fácil de entender en el shell.

Muestra los documentos de la colección userInformation:

> db.userInformation.find().pretty()

Producción :

{
        "_id" : ObjectId("628bc4a45c544feccff5a566"),
        "fullname" : "Mehvish Ashiq",
        "age" : 30,
        "gender" : "Female",
        "nationality" : "Pakistani"
}
{
        "_id" : ObjectId("628bc4a45c544feccff5a567"),
        "fullname" : "James Daniel",
        "age" : 45,
        "sex" : "male",
        "nationality" : "Canadian"
}

Mostrar documentos desde la userAddress:

> db.userAddress.find().pretty()

Producción :

{
        "_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"
}

Ambas colecciones deben estar en la misma base de datos para usar la etapa agregada $lookup. Una vez que ambas colecciones estén listas, podemos usar las diversas consultas para unir los datos de ambas colecciones según el escenario que tengamos.

Utilice la etapa agregada $lookup para unir dos colecciones en una

Código de ejemplo:

> db.userInformation.aggregate([
    { $lookup:
        {
           from: 'userAddress',
           localField: 'fullname',
           foreignField: 'fullname',
           as: 'address'
        }
    }
]).pretty();

Producción :

{
        "_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"
                }
        ]
}

En la base de datos de MongoDB, el $lookup etapa agregada realiza la unión externa izquierda con la otra colección y también filtra información (datos) de los documentos unidos. Por ejemplo, usamos la consulta para obtener la información de todos los usuarios con sus direcciones.

La función $lookup acepta cuatro campos. Primero está el campo from, donde especificamos la colección que se supone que debe unirse con la otra colección.

El segundo es el campo localField. Es uno de los atributos (campo) de los documentos de entrada de la colección especificados en el campo from.

Se utiliza para realizar una coincidencia en el localField con foreignField de los documentos de las colecciones.

De manera similar, el tercer campo llamado foreignField también realiza la coincidencia de igualdad en foreignField con localField de los documentos de las colecciones.

Escribimos el nombre de la nueva matriz para el cuarto campo, as. Consulte la siguiente explicación para la etapa agregada $lookup.

combine dos colecciones en una colección usando mongodb - explicación de la etapa de búsqueda

Utilice el operador pipeline para unir dos colecciones en una en función de la condición especificada

Código de ejemplo:

> db.userInformation.aggregate([{
    $lookup:{
        from: 'userAddress',
        let: {full_name: '$fullname'},
        pipeline: [{
            $match: {
                $expr: {
                    $eq: ['$fullname', '$$full_name']
                }
             }
       }],
       as: 'addressInfo'
    }
}]).pretty()

Producción :

{
        "_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"
                }
        ]
}

Podemos usar el operador pipeline con $lookup cuando queremos unir dos colecciones en función de una condición específica (al igual que usamos la cláusula WHERE en MySQL).

Por ejemplo, estamos uniendo las colecciones donde el fullname de userAddress es igual al fullname de userInformation.

Use el operador $unwind para la matriz plana antes de adjuntar a los documentos resultantes

Código de ejemplo:

> db.userInformation.aggregate([
    { $lookup:
        {
           from: 'userAddress',
           localField: 'fullname',
           foreignField: 'fullname',
           as: 'address'
        }
    },
    {
       $unwind: '$address'
    }
]).pretty();

Producción :

{
        "_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"
        }
}

El operador $unwind no hace nada más que aplanar la matriz antes de adjuntarla al documento resultante. La diferencia fundamental para el operador $unwind es que transforma una matriz con un solo elemento en el objeto aplanado, el elemento mismo.

Recuerde, el nombre de este elemento no se cambiará. Sería lo mismo que antes cuando el elemento estaba en forma de matriz.

Ejecute la consulta anterior con y sin el operador $unwind y observe el campo address.

Use la etapa de filtro $project en las consultas de agregación para unir dos colecciones en una

Antes de unir las colecciones usando el $project, entendamos su importancia. Por ejemplo, si no queremos unir toda la colección denominada userAddress con userInformation, sólo queremos unir los campos city y street.

En ese caso, necesitamos usar la etapa $addFields. Usamos esta etapa para unir/asignar cualquier campo o varios campos de una matriz/objeto al nivel raíz del documento.

Entonces, ejecutamos la siguiente consulta para recuperar la city y la street de la colección userAddress.

Código de ejemplo:

> db.userInformation.aggregate([
    { $lookup:
        {
           from: 'userAddress',
           localField: 'fullname',
           foreignField: 'fullname',
           as: 'address'
        }
    },
    {
       $unwind: '$address'
    },
    {
       $addFields: {
           street: '$address.street',
           city: '$address.city'
       }
    }
]).pretty();

Producción :

{
        "_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"
}

Concéntrese cuidadosamente en el resultado dado anteriormente. ¿Estamos consiguiendo la street y la city? Sí, obtenemos la street y la city en el nivel raíz del documento, pero también tenemos el objeto address que no necesitamos ahora.

Aquí es donde entra en escena la etapa de filtro $project. Especifica qué campos deberíamos tener en el documento resultante.

Consulte la siguiente consulta para una mejor comprensión.

Código de ejemplo:

> 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();

Producción :

{
        "_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"
}

Como puede ver, ahora no tenemos el objeto address, pero sus dos campos (street y city) están asignados al nivel raíz del documento.

Unir dos colecciones usando Compass (interfaz gráfica de MongoDB)

La agregación usando una interfaz gráfica es fácil. Solo necesitamos seguir los siguientes pasos para la etapa de agregación $lookup.

  1. Abra MongoDBCompass y conéctese al servidor.

  2. Cree una nueva base de datos y dos colecciones si lo desea. Usamos la misma base de datos y colecciones que creamos usando un shell de Mongo.

  3. Abra sus colecciones que se verán de la siguiente manera.

    combine dos colecciones en una colección usando mongodb - colecciones abiertas de brújula

  4. Agregue el escenario según los requisitos de su proyecto; añadimos la etapa de agregación $lookup. Actualice los campos $lookup y vea los resultados deseados en el lado derecho.

    combine dos colecciones en una colección usando mongodb - compass add lookup stage

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

Artículo relacionado - MongoDB Collection

Artículo relacionado - MongoDB Join