Combine dos colecciones en una colección usando MongoDB
- Combine dos colecciones en una colección usando MongoDB
-
Utilice la etapa agregada
$lookup
para unir dos colecciones en una -
Utilice el operador
pipeline
para unir dos colecciones en una en función de la condición especificada -
Use el operador
$unwind
para la matriz plana antes de adjuntar a los documentos resultantes -
Use la etapa de filtro
$project
en las consultas de agregación para unir dos colecciones en una - Unir dos colecciones usando Compass (interfaz gráfica de 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.
- Use la etapa agregada
$lookup
para unir dos colecciones - Utilice el operador
pipeline
para unir dos colecciones en función de la condición especificada - Use el operador
$unwind
para aplanar una matriz antes de adjuntarla a los documentos resultantes - Use la etapa de filtro
$project
en las consultas de agregación para unir dos colecciones - 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
.
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
.
-
Abra
MongoDBCompass
y conéctese al servidor. -
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.
-
Abra sus colecciones que se verán de la siguiente manera.
-
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.
Artículo relacionado - MongoDB Collection
- Agregue un nuevo campo a cada documento en una colección de MongoDB
- Colección truncada de MongoDB
- Comprobar si existe una colección en MongoDB usando NodeJS
- Descartar o eliminar una colección en MongoDB
- Eliminar duplicados en MongoDB