Para agentes de IA: hay un índice de documentación disponible en https://www.mongodb.com/es/docs/llms.txt — versiones en markdown de todas las páginas están disponibles agregando .md a cualquier ruta URL.
Docs Menu

$lookup (etapa de agregación)

$lookup

Cambiado en la versión 8.0.

Realiza una unión externa izquierda con una colección en la misma base de datos para el filtro de documentos de la colección foránea para su procesamiento. La etapa $lookup añade un nuevo campo de arreglo a cada documento de entrada. El nuevo campo de arreglo contiene los documentos coincidentes de la colección foránea. La etapa $lookup pasa estos documentos reformateados a la siguiente etapa.

A partir de MongoDB 5.1, puedes usar $lookup con colecciones particionadas.

Para combinar elementos de dos colecciones diferentes, utiliza la plataforma de $unionWith del pipeline.

Importante

$lookup el rendimiento, al igual que el de cualquier otra query, depende del tipo de operación y de si el campo externo está indexado. Las operaciones $lookup sin indexar o de subconsulta correlacionada en colecciones grandes pueden ralentizar el rendimiento de las query. Para reducir la dependencia de $lookup, considera un modelo de datos embebido para almacenar datos relacionados en una sola colección.

Para obtener detalles sobre el rendimiento de $lookup por tipo de operación, consulta Consideraciones sobre el rendimiento.

Puedes usar $lookup para implementaciones alojadas en los siguientes entornos:

  • MongoDB Atlas: El servicio totalmente gestionado para implementaciones de MongoDB en la nube
  • MongoDB Enterprise: La versión basada en suscripción y autogestionada de MongoDB

  • MongoDB Community: La versión de MongoDB con código fuente disponible, de uso gratuito y autogestionada.

La sintaxis de la etapa $lookup:

{
$lookup:
{
from: <collection to join>,
localField: <field from the input documents>,
foreignField: <field from the documents of the "from" collection>,
let: { <var_1>: <expression>, …, <var_n>: <expression> },
pipeline: [ <pipeline to run> ],
as: <output array field>
}
}

$lookup acepta un documento con estos campos:

Campo
Necesidad
Descripción

Requerido

Especifica la colección foránea en la misma base de datos para unirse a la colección local.

Es posible en algunos casos extremos sustituir from por pipeline usando $documents como la primera etapa. Para un ejemplo, consulta Usar una etapa $documents en una etapa $lookup.

A partir de MongoDB 5.1, la colección from se puede fragmentar.

Opcional si se especifica pipeline

Especifica el campo de la entrada de documentos para la etapa $lookup. $lookup realiza una coincidencia exacta en el localField con el foreignField de los documentos de la colección from. Si un documento de entrada no contiene el localField, el $lookup trata el campo como si tuviera un valor de null para fines de coincidencia.

Opcional si se especifica pipeline

Especifica los foreignField de los documentos foráneos para realizar una coincidencia exacta con los localField de los documentos locales.

Si un documento foráneo no contiene un valor foreignField, $lookup utiliza un valor null para la coincidencia.

Opcional

Especifica las variables que se deben usar en las etapas de la pipeline. Utiliza las expresiones de variables para acceder a los campos de los documentos de la colección local que se ingresan en pipeline.

Para referenciar variables en las etapas de un pipeline, utiliza la sintaxis "$$<variable>".

Se puede acceder a las variables let mediante las etapas de la pipeline, incluidas las etapas $lookup adicionales anidadas en el pipeline.

  • Una etapa $match requiere el uso de un operador $expr para acceder a las variables. El operador $expr permite el uso de expresiones de agregación dentro de la sintaxis de $match.

    Los operadores de comparación $eq, $lt, $lte, $gt y $gte colocados en un operador $expr pueden utilizar un índice en la colección from mencionada en una etapa $lookup. Limitaciones:

    • Los índices solo pueden utilizarse para comparaciones entre campos y constantes, por lo que el operando let debe resolverse en una constante.

      Por ejemplo, una comparación entre $a y un valor constante puede utilizar un índice, pero una comparación entre $a y $b no puede.

    • Los índices no se utilizan para comparaciones donde el operando let se resuelve en un valor vacío o faltante.

    • No se utilizan índices multiclave, parciales o dispersos.

  • Otras etapas (no$match) de la pipeline no requieren un $expr operador para acceder a las variables.

Opcional si se especifican localField y foreignField

Especifica el pipeline que se ejecutará en la colección foránea. El pipeline devuelve documentos de la colección externa. Para devolver todos los documentos, especifica un pipeline: [] vacío.

El pipeline no puede incluir las etapas de $out o $merge. A partir de la versión v6.0, la pipeline puede contener la etapa de MongoDB Search $search como la primera etapa dentro de la pipeline. Para aprender más, consulte Soporte de MongoDB Search.

El pipeline no puede acceder a los campos de los documentos de entrada. En su lugar, defina variables para los campos del documento usando la opción let y luego haga referencia a las variables en las etapas pipeline.

Para referenciar variables en las etapas de un pipeline, utiliza la sintaxis "$$<variable>".

Se puede acceder a las variables let mediante las etapas de la pipeline, incluidas las etapas $lookup adicionales anidadas en el pipeline.

  • Una etapa $match requiere el uso de un operador $expr para acceder a las variables. El operador $expr permite el uso de expresiones de agregación dentro de la sintaxis de $match.

    Los operadores de comparación $eq, $lt, $lte, $gt y $gte colocados en un operador $expr pueden utilizar un índice en la colección from mencionada en una etapa $lookup. Limitaciones:

    • Los índices solo pueden utilizarse para comparaciones entre campos y constantes, por lo que el operando let debe resolverse en una constante.

      Por ejemplo, una comparación entre $a y un valor constante puede utilizar un índice, pero una comparación entre $a y $b no puede.

    • Los índices no se utilizan para comparaciones donde el operando let se resuelve en un valor vacío o faltante.

    • No se utilizan índices multiclave, parciales o dispersos.

  • Otras etapas (no$match) de la pipeline no requieren un $expr operador para acceder a las variables.

Requerido

Especifica el nombre del nuevo campo de arreglo que se añadirá a los documentos de entrada. El nuevo campo de arreglo contiene los documentos coincidentes de la colección from. Si el nombre especificado ya existe en el documento de entrada, el campo existente se sobrescribe.

Para realizar una coincidencia exacta entre un campo de los documentos de entrada y un campo de los documentos de la colección externa, la etapa $lookup tiene esta sintaxis:

{
$lookup:
{
from: <collection to join>,
localField: <field from the input documents>,
foreignField: <field from the documents of the "from" collection>,
pipeline: [ <pipeline to run> ],
as: <output array field>
}
}

Nota

En este ejemplo, pipeline es opcional y se ejecuta después de la etapa de igualdad local y foránea.

La operación corresponde a esta instrucción pseudo-SQL:

SELECT *, (
SELECT ARRAY_AGG(*)
FROM <collection to join>
WHERE <foreignField> = <collection.localField>
) AS <output array field>
FROM collection;

Nota

Las instrucciones SQL de esta página se incluyen para compararlas con la sintaxis de la pipeline de agregación de MongoDB. Las instrucciones SQL no son ejecutables.

Para ejemplos de MongoDB, consulte estas páginas:

MongoDB admite:

  • Ejecución de una pipeline en una colección externa.

  • Múltiples condiciones de combinación.

  • Subconsultas correlacionadas y no correlacionadas.

En MongoDB, un sub-query no correlacionado significa que cada documento de entrada devuelve el mismo resultado. Un sub-query correlacionado es un pipeline en una $lookup etapa que utiliza los campos de la colección local o input para arrojar resultados correlacionados con cada documento entrante.

Nota

A partir de MongoDB 5.0, para un subquery no correlacionado en una $lookup etapa de la pipeline que contenga una etapa $sample, el operador $sampleRate o el operador $rand, el subquery siempre se ejecuta nuevamente si se repite. Anteriormente, según el tamaño del resultado del subquery, se almacenaba en caché o el subquery se ejecutaba nuevamente.

Las sub-query correlacionadas de MongoDB son comparables a las sub-query correlacionadas de SQL, donde la query interna hace referencia a los valores externos de la query. Una sub-query no correlacionada de SQL no hace referencia a valores de la query externa.

MongoDB 5.0 también soporta a los subquery correlacionados concisos.

Para realizar subconsultas correlacionadas y no correlacionadas con dos colecciones, y realizar otras condiciones de unión además de una única coincidencia exacta, utiliza esta sintaxis de $lookup:

{
$lookup:
{
from: <foreign collection>,
let: { <var_1>: <expression>, …, <var_n>: <expression> },
pipeline: [ <pipeline to run on foreign collection> ],
as: <output array field>
}
}

La operación corresponde a esta instrucción pseudo-SQL:

SELECT *, <output array field>
FROM collection
WHERE <output array field> IN (
SELECT <documents as determined from the pipeline>
FROM <collection to join>
WHERE <pipeline>
);

Vea los siguientes ejemplos:

Nuevo en la versión 5.0.

A partir de MongoDB 5.0, puedes usar una sintaxis concisa para una sub-query correlacionada. Las sub-query correlacionadas hacen referencia a campos de documentos de una colección foránea y de la colección "local" en la que se ejecutó el método aggregate().

La siguiente nueva sintaxis concisa remueve el requisito de una coincidencia exacta en los campos foráneo y local dentro de un operador $expr:

{
$lookup:
{
from: <foreign collection>,
localField: <field from local collection's documents>,
foreignField: <field from foreign collection's documents>,
let: { <var_1>: <expression>, …, <var_n>: <expression> },
pipeline: [ <pipeline to run> ],
as: <output array field>
}
}

La operación corresponde a esta instrucción pseudo-SQL:

SELECT *, <output array field>
FROM localCollection
WHERE <output array field> IN (
SELECT <documents as determined from the pipeline>
FROM <foreignCollection>
WHERE <foreignCollection.foreignField> = <localCollection.localField>
AND <pipeline match condition>
);

Vea este ejemplo:

A partir de MongoDB 8.1, puede referenciar múltipleS colecciones cifradas en una etapa de $lookup. Sin embargo, $lookup no brinda soporte:

  • Utilizando un campo cifrado como campo de unión en el localField o foreignField.

    Nota

    Para los controladores que usan cifrado a nivel de campo del lado del cliente, puedes usar un campo cifrado como campo de unión solo si estás realizando una operación de unión automática.

  • Usar cualquier campo en un arreglo cifrado. Un arreglo se considera cifrado si contiene algún elemento cifrado.

    • Por ejemplo, no puedes utilizar ningún campo dentro del arreglo como resultado de la operación $lookup, a menos que estés utilizando el cifrado a nivel de campo del lado del cliente y $unwind el campo as.

Si realizas una agregación que implique varias vistas, como con $lookup o $graphLookup, las vistas deben tener la misma intercalación.

No puedes incluir la $out o la $merge en la etapa $lookup. Es decir, al especificar un pipeline para la colección foránea, no puedes incluir ninguna de las etapas en el campo pipeline.

{
$lookup:
{
from: <collection to join>,
let: { <var_1>: <expression>, …, <var_n>: <expression> },
pipeline: [ <pipeline to execute on the foreign collection> ], // Cannot include $out or $merge
as: <output array field>
}
}

A partir de MongoDB 6.0, puedes especificar la etapa de MongoDB Search $search o $searchMeta en la pipeline $lookup para buscar colecciones en el clúster de Atlas. La etapa $search o la $searchMeta debe ser la primera etapa dentro de la pipeline $lookup.

Por ejemplo, cuando unes condiciones y subconsultas en una colección foránea o ejecutas subconsultas correlacionadas mediante sintaxis concisa, puedes especificar $search o $searchMeta dentro del pipeline, como se muestra a continuación:

Para ver un ejemplo de $lookup con $search, consulta el tutorial de MongoDB Search Ejecutar una query de MongoDB Search $search usando $lookup.

A partir de MongoDB 5.1, puedes especificar colecciones particionadas en el parámetro from de las etapas de $lookup.

A partir de MongoDB 8.0, puedes usar la etapa $lookup dentro de una transacción mientras apunta a una colección fragmentada.

A partir de la versión 6.0, MongoDB puede usar el motor de query de ejecución basado en ranuras para ejecutar las etapas $lookup si todas las etapas anteriores en el pipeline también se pueden ejecutar por el motor de ejecución basado en ranuras y ninguna de las siguientes condiciones es verdadera:

  • La operación $lookup ejecuta una pipeline en una colección foránea. Para ver un ejemplo de este tipo de operación, consulta Condiciones de unión y subconsultas en una colección foránea.

  • Los localField o foreignField de $lookup especifican componentes numéricos. Por ejemplo: { localField: "restaurant.0.review" }.

  • El campo from de cualquier $lookup en el pipeline especifica una vista o una colección fragmentada.

Para obtener más información, consulta $lookupOptimización.

$lookup el rendimiento depende del tipo de operación que se realice. Consulta la siguiente tabla para las consideraciones de rendimiento de las diferentes operaciones de $lookup.

$lookup Operación
Consideraciones sobre el rendimiento
  • $lookup Las operaciones que realizan coincidencias exactas con una sola unión funcionan mejor cuando la colección externa contiene un índice en el foreignField.

    IMPORTANTE: Si no existe un índice de apoyo en el foreignField, es probable que una operación $lookup que realice una coincidencia exacta con una sola unión tenga un rendimiento deficiente.

  • $lookup operaciones que contienen subqueries no correlacionadas funcionan mejor cuando el pipeline interno puede acceder a un índice de la colección externa.

  • MongoDB solo necesita ejecutar una vez la subquery $lookup antes de almacenar en caché la query porque no hay relación entre las colecciones de origen y las externas. La subquery no se basa en ningún valor de la colección de origen. Este comportamiento mejora el rendimiento para las ejecuciones posteriores de la operación $lookup.

  • $lookup las operaciones que contienen subconsultas correlacionadas tienen un mejor rendimiento cuando la colección externa contiene un índice en el foreignField.

  • Si tu pipeline pasa una gran cantidad de documentos a la query$lookup, las siguientes estrategias pueden mejorar el rendimiento:

    • Reduce el número de documentos que MongoDB pasa a la query $lookup. Por ejemplo, establece un filtro más estricto durante la etapa $match.

    • Reconsidere el esquema de los datos para asegurarse de que sea óptimo para el caso de uso.

Para estrategias generales de rendimiento, consulta las Estrategias de indexación y Optimización de query.

Los ejemplos de esta página utilizan datos del conjunto de datos sample_mflix. Para obtener más información sobre cómo cargar este conjunto de datos en la implementación autogestionada de MongoDB, consultar Cargar el conjunto de datos de muestra. Si realizó alguna modificación en las bases de datos de muestra, es posible que deba descartar y volver a crear las bases de datos para ejecutar los ejemplos de esta página.

La siguiente operación de agregación primero filtra la colección movies para películas con un runtime superior a 1000, y luego se une con la colección comments en los campos _id y movie_id:

db.movies.aggregate( [
{ $match: { runtime: { $gt: 1000 } } },
{
$lookup: {
from: "comments",
localField: "_id",
foreignField: "movie_id",
as: "movie_comments"
}
},
{
$project: {
_id: 0,
title: 1,
year: 1,
"movie_comments.name": 1,
"movie_comments.text": 1,
"movie_comments.date": 1
}
}
] )
[
{
title: 'Centennial',
year: 1978,
movie_comments: [
{
name: 'Ellaria Sand',
text: 'Excepturi nam nam eum possimus aspernatur autem. Quis nulla optio praesentium ut distinctio explicabo.',
date: ISODate('1995-08-18T03:01:50.000Z')
}
]
},
{ title: 'Baseball', year: 1994, movie_comments: [] }
]

La operación corresponde a esta instrucción pseudo-SQL:

SELECT *, movie_comments
FROM movies
WHERE movie_comments IN (
SELECT *
FROM comments
WHERE movie_id = movies._id
);

Para obtener más información, consulta Consideraciones sobre el rendimiento de la coincidencia exacta.

Si el localField es un arreglo, puedes comparar los elementos del arreglo contra un escalar foreignField sin una etapa de $unwind.

La siguiente operación de agregación une la colección movies con la colección users, emparejando el campo de arreglo cast de movies con el campo escalar name de users:

db.movies.aggregate( [
{
$match: {
title: {
$in: [ "Roger & Me", "The Sum of Us",
"Centennial" ]
}
}
},
{
$lookup: {
from: "users",
localField: "cast",
foreignField: "name",
as: "cast_users"
}
},
{
$project: {
_id: 0,
title: 1,
year: 1,
cast: 1,
"cast_users.name": 1,
"cast_users.email": 1
}
},
{ $sort: { year: 1 } }
] )
[
{
cast: [
'Raymond Burr',
'Barbara Carrera',
'Richard Chamberlain',
'Robert Conrad'
],
title: 'Centennial',
year: 1978,
cast_users: []
},
{
cast: [
'Michael Moore',
'Roger B. Smith',
'Rhonda Britton',
'Fred Ross'
],
title: 'Roger & Me',
year: 1989,
cast_users: [ { name: 'Michael Moore', email: 'michael_moore@fakegmail.com' } ]
},
{
cast: [
'Jack Thompson',
'Russell Crowe',
'John Polson',
'Deborah Kennedy'
],
title: 'The Sum of Us',
year: 1994,
cast_users: [
{
name: 'Deborah Kennedy',
email: 'deborah_kennedy@fakegmail.com'
}
]
}
]

El $mergeObjects operador combina múltiples documentos en un único documento.

La siguiente operación utiliza $lookup para unir la colección movies con la colección comments, luego utiliza $mergeObjects en $replaceRoot para fusionar el primer documento de comentario con el documento de película:

db.movies.aggregate( [
{ $match: { runtime: { $gt: 1000 } } },
{
$lookup: {
from: "comments",
localField: "_id",
foreignField: "movie_id",
as: "movie_comments"
}
},
{
$replaceRoot: {
newRoot: {
$mergeObjects: [
{ $arrayElemAt: [ "$movie_comments", 0 ] },
"$$ROOT"
]
}
}
},
{
$project: {
_id: 0,
title: 1,
year: 1,
genres: 1,
name: 1,
email: 1,
text: 1,
date: 1
}
}
] )
[
{
name: 'Ellaria Sand',
email: 'indira_varma@gameofthron.es',
text: 'Excepturi nam nam eum possimus aspernatur autem. Quis nulla optio praesentium ut distinctio explicabo.',
date: ISODate('1995-08-18T03:01:50.000Z'),
genres: [ 'Action', 'Adventure', 'Drama' ],
title: 'Centennial',
year: 1978
},
{
genres: [ 'Documentary', 'History', 'Sport' ],
title: 'Baseball',
year: 1994
}
]

Las pipelines pueden ejecutarse en una colección externa e incluir múltiples condiciones de unión. El operador $expr permite condiciones de unión más complejas, incluidas las conjunciones y las coincidencias inexactas.

Una condición de unión puede referirse a un campo en la colección local en la que se ejecutó el método aggregate() y referirse a un campo en la colección extranjera. Esto permite una sub-query correlacionada entre ambas colecciones.

MongoDB 5.0 soporta los subquery correlacionados concisos.

El siguiente ejemplo:

  • Une las colecciones movies y comments usando los campos _id y movie_id.

  • Filtra los comentarios para incluir únicamente aquellos publicados después del año de estreno de la película.

db.movies.aggregate( [
{
$match: {
title: {
$in: [ "Class Action", "Kafka", "Corpse Bride" ]
}
}
},
{
$lookup: {
from: "comments",
localField: "_id",
foreignField: "movie_id",
let: { movie_year: "$year" },
pipeline: [
{
$match: {
$expr: {
$gt: [
{ $year: "$date" }, "$$movie_year"
]
}
}
},
{ $project: { _id: 0, name: 1, date: 1 } }
],
as: "post_release_comments"
}
},
{
$project: {
_id: 0,
title: 1,
year: 1,
post_release_comments: 1
}
}
] )
[
{
year: 1991,
title: 'Class Action',
post_release_comments: [
{ name: 'Khal Drogo', date: ISODate('2016-12-06T07:17:03.000Z') }
]
},
{
year: 1991,
title: 'Kafka',
post_release_comments: [
{ name: 'Khal Drogo', date: ISODate('1998-05-10T03:10:20.000Z') }
]
},
{ year: 2005, title: 'Corpse Bride', post_release_comments: [] }
]

La operación corresponde a esta instrucción pseudo-SQL:

SELECT *, post_release_comments
FROM movies
WHERE post_release_comments IN (
SELECT name, date
FROM comments
WHERE movie_id = movies._id
AND YEAR(date) > movies.year
);

Los operadores de comparación $eq, $lt, $lte, $gt y $gte colocados en un operador $expr pueden utilizar un índice en la colección from mencionada en una etapa $lookup. Limitaciones:

  • Los índices solo pueden utilizarse para comparaciones entre campos y constantes, por lo que el operando let debe resolverse en una constante.

    Por ejemplo, una comparación entre $a y un valor constante puede utilizar un índice, pero una comparación entre $a y $b no puede.

  • Los índices no se utilizan para comparaciones donde el operando let se resuelve en un valor vacío o faltante.

  • No se utilizan índices multiclave, parciales o dispersos.

Por ejemplo, si el índice { movie_id: 1 } existe en la colección comments:

  • La coincidencia exacta en el campo comments.movie_id utiliza el índice.

Una etapa de $lookup de una pipeline de agregación puede ejecutar una pipeline en la colección foránea, lo que permite subconsultas no correlacionadas. Una sub-query no correlacionada no hace referencia a los campos locales del documento.

Nota

A partir de MongoDB 5.0, para un subquery no correlacionado en una $lookup etapa de la pipeline que contenga una etapa $sample, el operador $sampleRate o el operador $rand, el subquery siempre se ejecuta nuevamente si se repite. Anteriormente, según el tamaño del resultado del subquery, se almacenaba en caché o el subquery se ejecutaba nuevamente.

La siguiente operación une la colección users con las películas que tienen una duración superior a 1000 minutos, pertenecientes a la colección movies:

db.users.aggregate( [
{
$match: {
email: { $in: [
"mark_addy@gameofthron.es",
"lena_headey@gameofthron.es"
] }
}
},
{
$lookup: {
from: "movies",
pipeline: [
{ $match: { runtime: { $gt: 1000 } } },
{ $project: { _id: 0, title: 1, year: 1 } }
],
as: "long_movies"
}
},
{
$project: {
_id: 0, name: 1, email: 1, long_movies: 1
}
}
] )
[
{
name: 'Robert Baratheon',
email: 'mark_addy@gameofthron.es',
long_movies: [
{ title: 'Centennial', year: 1978 },
{ title: 'Baseball', year: 1994 }
]
},
{
name: 'Cersei Lannister',
email: 'lena_headey@gameofthron.es',
long_movies: [
{ title: 'Centennial', year: 1978 },
{ title: 'Baseball', year: 1994 }
]
}
]

La operación corresponde a esta instrucción pseudo-SQL:

SELECT *, long_movies
FROM users
WHERE long_movies IN (
SELECT title, year
FROM movies
WHERE runtime > 1000
);

Para obtener más información, consulta Consideraciones sobre el rendimiento de subquery no correlacionado.

Nuevo en la versión 5.0.

A partir de MongoDB 5.0, una etapa de $lookup de la pipeline de agregación admite una sintaxis concisa de subquery correlacionado que mejora las uniones entre colecciones. La nueva sintaxis concisa remueve el requisito de una coincidencia exacta en los campos foráneos y locales dentro de un operador $expr en una etapa $match.

El siguiente ejemplo:

  • Une las colecciones movies y comments al emparejar el localField _id con el foreignField movie_id. La coincidencia se realiza antes de que se ejecute pipeline.

  • Filtra los comentarios para incluir solo aquellos publicados después del año de estreno de la película, accediendo respectivamente mediante $$movie_year y $date.

db.movies.aggregate( [
{
$match: {
title: { $in: [
"I Don't Kiss",
"Lucky Luke",
"Mississippi Masala"
] }
}
},
{
$lookup: {
from: "comments",
localField: "_id",
foreignField: "movie_id",
let: { movie_year: "$year" },
pipeline: [
{
$match: {
$expr: {
$gt: [
{ $year: "$date" }, "$$movie_year"
]
}
}
},
{ $project: { _id: 0, name: 1, date: 1 } }
],
as: "post_release_comments"
}
},
{
$project: {
_id: 0,
title: 1,
year: 1,
post_release_comments: 1
}
}
] )
[
{
title: "I Don't Kiss",
year: 1991,
post_release_comments: [
{
name: 'Brandon Hardy',
date: ISODate('2016-09-18T11:11:34.000Z')
}
]
},
{
title: 'Lucky Luke',
year: 1991,
post_release_comments: [
{
name: 'Kelsey Smith',
date: ISODate('2010-01-13T17:55:01.000Z')
}
]
},
{
title: 'Mississippi Masala',
year: 1991,
post_release_comments: [
{
name: 'Phillip Collins',
date: ISODate('2010-05-13T08:04:22.000Z')
}
]
}
]

Este ejemplo utiliza la sintaxis detallada de las versiones de MongoDB anteriores a la 5.0 y arroja los mismos resultados que el ejemplo conciso anterior:

db.movies.aggregate( [
{
$match: {
title: { $in: [
"I Don't Kiss",
"Lucky Luke",
"Mississippi Masala"
] }
}
},
{
$lookup: {
from: "comments",
let: { movie_id: "$_id", movie_year: "$year" },
pipeline: [
{
$match: {
$expr: {
$and: [
{ $eq: [ "$movie_id", "$$movie_id" ] },
{ $gt: [
{ $year: "$date" }, "$$movie_year"
] }
]
}
}
},
{ $project: { _id: 0, name: 1, date: 1 } }
],
as: "post_release_comments"
}
},
{
$project: {
_id: 0,
title: 1,
year: 1,
post_release_comments: 1
}
}
] )
[
{
title: "I Don't Kiss",
year: 1991,
post_release_comments: [
{
name: 'Brandon Hardy',
date: ISODate('2016-09-18T11:11:34.000Z')
}
]
},
{
title: 'Lucky Luke',
year: 1991,
post_release_comments: [
{
name: 'Kelsey Smith',
date: ISODate('2010-01-13T17:55:01.000Z')
}
]
},
{
title: 'Mississippi Masala',
year: 1991,
post_release_comments: [
{
name: 'Phillip Collins',
date: ISODate('2010-05-13T08:04:22.000Z')
}
]
}
]

Los ejemplos anteriores corresponden a esta instrucción pseudo-SQL:

SELECT *, post_release_comments
FROM movies
WHERE post_release_comments IN (
SELECT *
FROM comments
WHERE comments.movie_id = movies._id
AND YEAR(comments.date) > movies.year
);

Para obtener más información, consulta Consideraciones sobre el rendimiento de los subquery correlacionados.

A partir de MongoDB 8.0, namespaces en subpipelines dentro de $lookup y $unionWith se validan para asegurar el uso correcto de los campos from y coll:

  • Para $lookup, omite el campo from si utilizas una subpipeline con una etapa que no requiera una colección especificada. Por ejemplo, una etapa $documents.

  • De manera similar, para $unionWith, omite el campo coll.

Comportamiento sin cambio:

  • Para un $lookup que comienza con una etapa para una colección, por ejemplo, una sub-etapa $match o $collStats, debes incluir el campo from y especificar la colección.

  • De manera similar, para $unionWith, incluye el campo coll y especifica la colección.

El siguiente escenario muestra un ejemplo.

Cree una colección cakeFlavors:

db.cakeFlavors.insertMany( [
{ _id: 1, flavor: "chocolate" },
{ _id: 2, flavor: "strawberry" },
{ _id: 3, flavor: "cherry" }
] )