Definição
- $lookup
- Alterado na versão 5.1. - Executa uma junção externa esquerda em uma coleção no mesmo banco de dados para filtrar documentos da coleção estrangeira para processamento. O estágio - $lookupadiciona um novo campo de matriz para cada documento de entrada. O novo campo de array contém os documentos correspondentes da coleção estrangeira. O estágio- $lookuppassa esses documentos remodelados para o próximo estágio.- A partir do MongoDB 5.1, é possível usar - $lookupcom coleções fragmentadas.- Para combinar elementos de duas coleções diferentes, use o estágio de pipeline - $unionWith.
Compatibilidade
Você pode utilizar o $lookup para implantações hospedadas nos seguintes ambientes:
- MongoDB Atlas: o serviço totalmente gerenciado para implantações do MongoDB na nuvem 
- MongoDB Enterprise: a versão autogerenciada e baseada em assinatura do MongoDB 
- MongoDB Community: uma versão com código disponível, de uso gratuito e autogerenciada do MongoDB 
Sintaxe
A sintaxe de estágio $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>      } } 
O $lookup aceita um documento com estes campos:
| Campo | necessidade | Descrição | 
|---|---|---|
| Obrigatório | Especifica a coleção estrangeira no mesmo banco de dados para ingressar na coleção local. É possível, em alguns casos extremos, substituir  A partir do MongoDB 5.1, a coleção  | |
| Opcional se  | Especifica o campo da entrada de documentos para o  | |
| Opcional se  | Especifica o  Se um documento externo não contiver um  | |
| Opcional | Especifica variáveis a serem usadas nos estágios do pipeline. Use as expressões variáveis para acessar os campos dos documentos da coleção local que são inseridos no  Para fazer referência a variáveis em  estágios do pipeline, use a  As variáveis let podem ser acessadas pelos estágios no pipeline, incluindo os estágios adicionais  
 | |
| Opcional se  | Especifica o  O  O  Para fazer referência a variáveis em  estágios do pipeline, use a  As variáveis let podem ser acessadas pelos estágios no pipeline, incluindo os estágios adicionais  
 | |
| Obrigatório | Especifica o nome do novo campo de array a ser adicionado aos documentos de entrada. O novo campo de array contém os documentos correspondentes da coleção  | 
Correspondência de igualdade com uma única condição de junção
Para realizar uma correspondência de igualdade entre um campo dos documentos de entrada e um campo dos documentos da coleção estrangeira, a etapa $lookup tem a seguinte sintaxe:
{    $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>      } } 
Observação
Neste exemplo, pipeline é opcional e executado após o estágio de igualdade local e externa.
A operação corresponde a esta declaração pseudo-SQL:
SELECT *, (    SELECT ARRAY_AGG(*)    FROM <collection to join>    WHERE <foreignField> = <collection.localField> ) AS <output array field> FROM collection; 
Observação
As declarações SQL nesta página estão incluídas para comparação com a sintaxe do pipeline de agregação do MongoDB. As declarações SQL não são executáveis.
Para exemplos do MongoDB, consulte estas páginas:
Condições de junção e subqueries em uma coleção estrangeira
MongoDB suporta:
- Executando um pipeline em uma coleção estrangeira. 
- Várias condições de junções. 
- Subconsultas correlacionadas e não correlacionadas. 
No MongoDB, uma subquery não correlacionada significa que todo documento de entrada retornará o mesmo resultado. Uma subquery correlacionada é um pipeline em um estágio$lookup que usa os campos da collection local ou input para retornar resultados correlacionados a cada documento recebido.
Observação
A partir do MongoDB 5.0, para uma sub-query não correlacionada em um estágio de pipeline $lookup que contém um estágio $sample, o operador $sampleRate ou o operador $rand, a sub-query é sempre executada novamente se for repetida. Anteriormente, dependendo do tamanho da saída da sub-query, o resultado da sub-query era armazenado em cache ou a sub-query era executada novamente.
As subconsultas correlacionadas do MongoDB são comparáveis às subconsultas correlacionadas do SQL, onde a consulta interna faz referência a valores de consulta externa. Uma subconsulta SQL não correlacionada não faz referência a valores de consulta externa.
O MongoDB 5.0 também suporta subqueries correlacionadas concisas.
Para executar subconsultas correlacionadas e não correlacionadas com duas coleções e executar outras condições de junção além de uma única correspondência de igualdade, use esta sintaxe $lookup:
{    $lookup:       {          from: <foreign collection>,          let: { <var_1>: <expression>, …, <var_n>: <expression> },          pipeline: [ <pipeline to run on foreign collection> ],          as: <output array field>       } } 
A operação corresponde a esta declaração 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> ); 
Veja os seguintes exemplos:
Subconsultas correlacionadas usando sintaxe concisa
Novidades na versão 5.0.
A partir do MongoDB 5.0, você pode usar uma sintaxe concisa para uma subquery correlacionada. As subqueries correlacionadas fazem referência a campos de documentos de uma coleção estrangeira e da coleção "local" na qual o método aggregate() foi executado.
A nova sintaxe concisa a seguir remove o requisito de uma correspondência de igualdade nos campos estrangeiros e local dentro de um 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>       } } 
A operação corresponde a esta declaração 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> ); 
Veja este exemplo:
Comportamento
Visualizações e agrupamento
Se executar uma agregação que envolva múltiplas visualizações, como com $lookup ou $graphLookup, as visualizações deverão ter o mesmo agrupamento.
Restrições
Você não pode incluir os estágios $out ou $merge no estágio $lookup. Ou seja, ao especificar um pipeline para a coleção estrangeira, você não pode incluir nenhum dos estágios no 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>    } } 
Suporte do Atlas Search
A partir do MongoDB 6.0, você pode especificar o $search do Atlas Search  ou o estágio do $searchMeta no pipeline de $lookup para pesquisar coleções no cluster do Atlas. O estágio $search ou $searchMeta deve ser o primeiro dentro do pipeline $lookup.
Por exemplo, ao realizar Condições de junção e subqueries em uma coleção estrangeira ou executar Subqueries correlacionadas usando sintaxe concisa, você pode especificar $search ou $searchMeta dentro do pipeline, conforme mostrado abaixo:
Para ver um exemplo de $lookup com $search, consulte o tutorial Executar uma query $search do Atlas Search usando $lookup, do Atlas Search.
Coleções fragmentadas
A partir do MongoDB 5.1, você pode especificar coleções fragmentadas no parâmetro from de $lookup estágios.
Você não pode usar a etapa $lookup dentro de uma transação enquanto segmenta uma coleção fragmentada.
Mecanismo de execução de consulta baseado em slot
Observação
A partir da versão 7.0.17, o mecanismo de execução de queries baseado em slots não está mais ativado por padrão para versões de patch do 7.0. Se você deseja que suas queries usem o mecanismo de execução de queries baseado em slots, atualize para a versão 8.0, onde está habilitado por padrão.
A partir da versão 6.0, o MongoDB pode usar o mecanismo de execução de query baseado em slots para executar $lookup estágios se todos os estágios anteriores no pipeline também puderem ser executados pelo mecanismo de execução baseado em slots e nenhuma das seguintes condições for verdadeira:
- A operação - $lookupexecuta um pipeline em uma coleção estrangeira. Para ver um exemplo desse tipo de operação, consulte Condições de união e subqueries em uma coleção estrangeira.
- Os - localFieldou- foreignFieldde- $lookupespecificam componentes numéricos. Por exemplo:- { localField: "restaurant.0.review" }.
- O campo - fromde qualquer- $lookupno pipeline especifica uma visualização ou coleção fragmentada.
Para mais informações, consulte Otimização do$lookup.
Considerações de desempenho
$lookup o desempenho depende do tipo de operação executada. Consulte a tabela a seguir para considerações de desempenho para diferentes operações do $lookup.
| $lookup(operação) | Considerações de desempenho | 
|---|---|
| 
 | |
| 
 | |
| 
 | 
Para obter estratégias gerais de desempenho, consulte Estratégias de indexação e Otimização de consulta.
Importante
O uso excessivo de $lookup em uma consulta pode diminuir o desempenho. Para evitar vários estágios $lookup, adote um modelo de dados embutido para melhorar o desempenho da consulta.
Exemplos
Realizar uma única junção de igualdade com $lookup
Crie uma coleção orders com estes documentos:
db.orders.insertMany( [    { _id: 1, item: "almonds", price: 12, quantity: 2 },    { _id: 2, item: "pecans", price: 20, quantity: 1 },    { _id: 3  } ] ) 
Crie outra coleção inventory com estes documentos:
db.inventory.insertMany( [    { _id: 1, sku: "almonds", description: "product 1", instock: 120 },    { _id: 2, sku: "bread", description: "product 2", instock: 80 },    { _id: 3, sku: "cashews", description: "product 3", instock: 60 },    { _id: 4, sku: "pecans", description: "product 4", instock: 70 },    { _id: 5, sku: null, description: "Incomplete" },    { _id: 6 } ] ) 
A operação de agregação a seguir na coleção orders une os documentos de orders com os documentos da coleção inventory usando os campos item da coleção orders e o campo sku da coleção inventory:
db.orders.aggregate( [    {      $lookup:        {          from: "inventory",          localField: "item",          foreignField: "sku",          as: "inventory_docs"        }   } ] ) 
A operação retorna estes documentos:
{    _id: 1,    item: "almonds",    price: 12,    quantity: 2,    inventory_docs: [       { _id: 1, sku: "almonds", description: "product 1", instock: 120 }    ] } {    _id: 2,    item: "pecans",    price: 20,    quantity: 1,    inventory_docs: [       { _id: 4, sku: "pecans", description: "product 4", instock: 70 }    ] } {    _id: 3,    inventory_docs: [       { _id: 5, sku: null, description: "Incomplete" },       { _id: 6 }    ] } 
A operação corresponde a esta declaração pseudo-SQL:
SELECT *, inventory_docs FROM orders WHERE inventory_docs IN (    SELECT *    FROM inventory    WHERE sku = orders.item ); 
Para obter mais informações, consulte Considerações sobre o desempenho da correspondência de igualdade.
Use $lookup com uma array
Se localField for uma array, você poderá fazer a correspondência dos elementos de array com um escalar foreignField sem um estágio $unwind.
Por exemplo, crie uma coleção de exemplo classes com estes documentos:
db.classes.insertMany( [    { _id: 1, title: "Reading is ...", enrollmentlist: [ "giraffe2", "pandabear", "artie" ], days: ["M", "W", "F"] },    { _id: 2, title: "But Writing ...", enrollmentlist: [ "giraffe1", "artie" ], days: ["T", "F"] } ] ) 
Crie outra coleção members com estes documentos:
db.members.insertMany( [    { _id: 1, name: "artie", foreign: new Date("2016-05-01"), status: "A" },    { _id: 2, name: "giraffe", foreign: new Date("2017-05-01"), status: "D" },    { _id: 3, name: "giraffe1", foreign: new Date("2017-10-01"), status: "A" },    { _id: 4, name: "panda", foreign: new Date("2018-10-11"), status: "A" },    { _id: 5, name: "pandabear", foreign: new Date("2018-12-01"), status: "A" },    { _id: 6, name: "giraffe2", foreign: new Date("2018-12-01"), status: "D" } ] ) 
A seguinte operação de agregação une documentos na coleção classes com a coleção members, correspondendo o campo enrollmentlist ao campo name:
db.classes.aggregate( [    {       $lookup:          {             from: "members",             localField: "enrollmentlist",             foreignField: "name",             as: "enrollee_info"         }    } ] ) 
A operação retorna o seguinte:
{    _id: 1,    title: "Reading is ...",    enrollmentlist: [ "giraffe2", "pandabear", "artie" ],    days: [ "M", "W", "F" ],    enrollee_info: [       { _id: 1, name: "artie", foreign: ISODate("2016-05-01T00:00:00Z"), status: "A" },       { _id: 5, name: "pandabear", foreign: ISODate("2018-12-01T00:00:00Z"), status: "A" },       { _id: 6, name: "giraffe2", foreign: ISODate("2018-12-01T00:00:00Z"), status: "D" }    ] } {    _id: 2,    title: "But Writing ...",    enrollmentlist: [ "giraffe1", "artie" ],    days: [ "T", "F" ],    enrollee_info: [       { _id: 1, name: "artie", foreign: ISODate("2016-05-01T00:00:00Z"), status: "A" },       { _id: 3, name: "giraffe1", foreign: ISODate("2017-10-01T00:00:00Z"), status: "A" }    ] } 
Usar $lookup com $mergeObjects
O operador $mergeObjects combina vários documentos em um único documento.
Crie uma coleção orders com estes documentos:
db.orders.insertMany( [    { _id: 1, item: "almonds", price: 12, quantity: 2 },    { _id: 2, item: "pecans", price: 20, quantity: 1 } ] ) 
Crie outra coleção items com estes documentos:
db.items.insertMany( [   { _id: 1, item: "almonds", description: "almond clusters", instock: 120 },   { _id: 2, item: "bread", description: "raisin and nut bread", instock: 80 },   { _id: 3, item: "pecans", description: "candied pecans", instock: 60 } ] ) 
A operação a seguir usa primeiro o estágio $lookup para unir as duas coleções pelos campos item e, em seguida, usa $mergeObjects no $replaceRoot para mesclar os documentos externos de items e orders:
db.orders.aggregate( [    {       $lookup: {          from: "items",          localField: "item",    // field in the orders collection          foreignField: "item",  // field in the items collection          as: "fromItems"       }    },    {       $replaceRoot: { newRoot: { $mergeObjects: [ { $arrayElemAt: [ "$fromItems", 0 ] }, "$$ROOT" ] } }    },    { $project: { fromItems: 0 } } ] ) 
A operação retorna estes documentos:
{   _id: 1,   item: 'almonds',   description: 'almond clusters',   instock: 120,   price: 12,   quantity: 2 }, {   _id: 2,   item: 'pecans',   description: 'candied pecans',   instock: 60,   price: 20,   quantity: 1 } 
Use várias condições de junção e uma subquery correlacionada
Os pipelines podem ser executados em uma coleção estrangeira e incluir diversas condições de junção. O operador $expr permite condições de junção mais complexas, incluindo conjunções e correspondências de não igualdade.
Uma condição de junção pode fazer referência a um campo na coleção local na qual o método aggregate() foi executado e fazer referência a um campo na coleção estrangeira. Isso permite uma subquery correlacionada entre as duas coleções.
O MongoDB 5.0 é compatível com subconsultas correlacionadas concisas.
Crie uma coleção orders com estes documentos:
db.orders.insertMany( [   { _id: 1, item: "almonds", price: 12, ordered: 2 },   { _id: 2, item: "pecans", price: 20, ordered: 1 },   { _id: 3, item: "cookies", price: 10, ordered: 60 } ] ) 
Crie outra coleção warehouses com estes documentos:
db.warehouses.insertMany( [   { _id: 1, stock_item: "almonds", warehouse: "A", instock: 120 },   { _id: 2, stock_item: "pecans", warehouse: "A", instock: 80 },   { _id: 3, stock_item: "almonds", warehouse: "B", instock: 60 },   { _id: 4, stock_item: "cookies", warehouse: "B", instock: 40 },   { _id: 5, stock_item: "cookies", warehouse: "A", instock: 80 } ] ) 
O seguinte exemplo:
- Usa uma subconsulta correlacionada com uma junção nos campos - orders.iteme- warehouse.stock_item.
- Garante que a quantidade do item em estoque possa atender à quantidade solicitada. 
db.orders.aggregate( [    {       $lookup:          {            from : "warehouses",            localField : "item",            foreignField : "stock_item",            let : { order_qty: "$ordered" },            pipeline : [               { $match :                  { $expr :                       { $gte: [ "$instock", "$$order_qty" ] }                  }               },               { $project : { stock_item: 0, _id: 0 } }            ],            as : "stockdata"          }     } ] ) 
A operação retorna estes documentos:
{   _id: 1,   item: 'almonds',   price: 12,   ordered: 2,   stockdata: [     { warehouse: 'A', instock: 120 },     { warehouse: 'B', instock: 60 }   ] }, {   _id: 2,   item: 'pecans',   price: 20,   ordered: 1,   stockdata: [ { warehouse: 'A', instock: 80 } ] }, {   _id: 3,   item: 'cookies',   price: 10,   ordered: 60,   stockdata: [ { warehouse: 'A', instock: 80 } ] } 
A operação corresponde a esta declaração pseudo-SQL:
SELECT *, stockdata FROM orders WHERE stockdata IN (    SELECT warehouse, instock    FROM warehouses    WHERE stock_item = orders.item    AND instock >= orders.ordered ); 
Os operadores de comparação $eq, $lt, $lte, $gt e $gte colocados em um operador $expr podem utilizar um índice na coleção from referenciada em um estágio $lookup. Limitações:
- Os índices só podem ser usados para comparações entre campos e constantes, portanto, o operando - letdeve ser resolvido para uma constante.- Por exemplo, uma comparação entre - $ae um valor constante pode usar um índice, mas uma comparação entre- $ae- $bnão pode.
- Os índices não são usados para comparações onde o operando - letresolve para um valor vazio ou ausente.
- Índices multichave não são usados. 
Por exemplo, se o índice { stock_item: 1, instock: 1 } existir na coleção warehouses:
- A correspondência de igualdade no campo - warehouses.stock_itemutiliza o índice.
- A parte da faixa da consulta no campo - warehouses.instocktambém utiliza o campo indexado no índice composto.
Execute uma subconsulta não correlacionada $lookup
Um estágio $lookup do pipeline de agregação pode executar um pipeline na coleção estrangeira, o que permite subqueries não correlacionadas. Uma subquery não correlacionada não faz referência aos campos do documento local.
Observação
A partir do MongoDB 5.0, para uma sub-query não correlacionada em um estágio de pipeline $lookup que contém um estágio $sample, o operador $sampleRate ou o operador $rand, a sub-query é sempre executada novamente se for repetida. Anteriormente, dependendo do tamanho da saída da sub-query, o resultado da sub-query era armazenado em cache ou a sub-query era executada novamente.
Crie uma coleção absences com estes documentos:
db.absences.insertMany( [    { _id: 1, student: "Ann Aardvark", sickdays: [ new Date ("2018-05-01"),new Date ("2018-08-23") ] },    { _id: 2, student: "Zoe Zebra", sickdays: [ new Date ("2018-02-01"),new Date ("2018-05-23") ] }, ] ) 
Crie outra coleção holidays com estes documentos:
db.holidays.insertMany( [    { _id: 1, year: 2018, name: "New Years", date: new Date("2018-01-01") },    { _id: 2, year: 2018, name: "Pi Day", date: new Date("2018-03-14") },    { _id: 3, year: 2018, name: "Ice Cream Day", date: new Date("2018-07-15") },    { _id: 4, year: 2017, name: "New Years", date: new Date("2017-01-01") },    { _id: 5, year: 2017, name: "Ice Cream Day", date: new Date("2017-07-16") } ] ) 
A operação a seguir une a coleção absences às informações de feriados de 2018 da coleção holidays:
db.absences.aggregate( [    {       $lookup:          {            from: "holidays",            pipeline: [               { $match: { year: 2018 } },               { $project: { _id: 0, date: { name: "$name", date: "$date" } } },               { $replaceRoot: { newRoot: "$date" } }            ],            as: "holidays"          }     } ] ) 
A operação retorna o seguinte:
{   _id: 1,   student: 'Ann Aardvark',   sickdays: [     ISODate("2018-05-01T00:00:00.000Z"),     ISODate("2018-08-23T00:00:00.000Z")   ],   holidays: [     { name: 'New Years', date: ISODate("2018-01-01T00:00:00.000Z") },     { name: 'Pi Day', date: ISODate("2018-03-14T00:00:00.000Z") },     { name: 'Ice Cream Day', date: ISODate("2018-07-15T00:00:00.000Z")     }   ] }, {   _id: 2,   student: 'Zoe Zebra',   sickdays: [     ISODate("2018-02-01T00:00:00.000Z"),     ISODate("2018-05-23T00:00:00.000Z")   ],   holidays: [     { name: 'New Years', date: ISODate("2018-01-01T00:00:00.000Z") },     { name: 'Pi Day', date: ISODate("2018-03-14T00:00:00.000Z") },     { name: 'Ice Cream Day', date: ISODate("2018-07-15T00:00:00.000Z")     }   ] } 
A operação corresponde a esta declaração pseudo-SQL:
SELECT *, holidays FROM absences WHERE holidays IN (    SELECT name, date    FROM holidays    WHERE year = 2018 ); 
Para obter mais informações, consulte Considerações sobre desempenho de subconsultas não correlacionadas.
Execute uma subconsulta concisa correlacionada com $lookup
Novidades na versão 5.0.
A partir do MongoDB 5.0, um estágio $lookup do pipeline de agregação suporta uma sintaxe de sub-query correlacionada concisa que melhora as uniões entre coleções. A nova sintaxe concisa remove a exigência de uma correspondência de igualdade nos campos externo e local dentro de um operador $expr em um estágio $match.
Criar uma coleção restaurants:
db.restaurants.insertMany( [    {       _id: 1,       name: "American Steak House",       food: [ "filet", "sirloin" ],       beverages: [ "beer", "wine" ]    },    {       _id: 2,       name: "Honest John Pizza",       food: [ "cheese pizza", "pepperoni pizza" ],       beverages: [ "soda" ]    } ] ) 
Crie outra coleção orders com pedidos de comidas e bebidas opcionais:
db.orders.insertMany( [    {       _id: 1,       item: "filet",       restaurant_name: "American Steak House"    },    {       _id: 2,       item: "cheese pizza",       restaurant_name: "Honest John Pizza",       drink: "lemonade"    },    {       _id: 3,       item: "cheese pizza",       restaurant_name: "Honest John Pizza",       drink: "soda"    } ] ) 
O seguinte exemplo:
- Associa as coleções - orderse- restaurantscombinando o- orders.restaurant_namelocalField com o- restaurants.nameforeignField. A correspondência é executada antes de- pipelineser executado.
- Realiza uma correspondência de array - $inentre os campos- orders.drinke- restaurants.beveragesque são acessados usando- $$orders_drinke- $beverages, respectivamente.
db.orders.aggregate( [    {       $lookup: {          from: "restaurants",          localField: "restaurant_name",          foreignField: "name",          let: { orders_drink: "$drink" },          pipeline: [ {             $match: {                $expr: { $in: [ "$$orders_drink", "$beverages" ] }             }          } ],          as: "matches"       }    } ] ) 
Há uma correspondência para o valor soda nos campos orders.drink e restaurants.beverages. Esta saída exibe o array matches e inclui todos os campos estrangeiros da coleção restaurants para a correspondência:
{    _id: 1, item: "filet",    restaurant_name: "American Steak House",    matches: [ ] } {    _id: 2, item: "cheese pizza",    restaurant_name: "Honest John Pizza",    drink: "lemonade",    matches: [ ] } {    _id: 3, item: "cheese pizza",    restaurant_name: "Honest John Pizza",    drink: "soda",    matches: [ {       _id: 2, name": "Honest John Pizza",       food: [ "cheese pizza", "pepperoni pizza" ],       beverages: [ "soda" ]    } ] } 
Este exemplo usa a sintaxe detalhada mais antiga das versões do MongoDB anteriores à 5.0 e retorna os mesmos resultados do exemplo conciso anterior:
db.orders.aggregate( [    {       $lookup: {          from: "restaurants",          let: { orders_restaurant_name: "$restaurant_name",                 orders_drink: "$drink" },          pipeline: [ {             $match: {                $expr: {                   $and: [                      { $eq: [ "$$orders_restaurant_name", "$name" ] },                      { $in: [ "$$orders_drink", "$beverages" ] }                   ]                }             }          } ],          as: "matches"       }    } ] ) 
Os exemplos anteriores correspondem a esta declaração pseudo-SQL:
SELECT *, matches FROM orders WHERE matches IN (    SELECT *    FROM restaurants    WHERE restaurants.name = orders.restaurant_name    AND restaurants.beverages = orders.drink ); 
Para mais informações, consulte Considerações sobre o desempenho de subconsultas correlacionadas.
Os exemplos de C# nesta página utilizam o banco de dados sample_mflix a partir dos conjuntos de dados de amostra do Atlas. Para saber como criar um cluster MongoDB Atlas gratuito e carregar os conjuntos de dados de exemplo, consulte Introdução na documentação do driver MongoDB .NET/C#.
A seguinte classe Movie modela os documentos na collection sample_mflix.movies:
public class Movie {     public ObjectId Id { get; set; }     public int Runtime { get; set; }          public string Title { get; set; }     public string Rated { get; set; }     public List<string> Genres { get; set; }     public string Plot { get; set; }          public ImdbData Imdb { get; set; }     public int Year { get; set; }     public int Index { get; set; }          public string[] Comments { get; set; }         []     public DateTime LastUpdated { get; set; } } 
Observação
ConventionPack para Pascal Case
As classes C# nesta página usam Pascal case para seus nomes de propriedade, mas os nomes de campo na coleção MongoDB usam Camel case. Para considerar essa diferença, você pode usar o seguinte código para registrar um ConventionPack quando o aplicativo iniciar:
var camelCaseConvention = new ConventionPack { new CamelCaseElementNameConvention() }; ConventionRegistry.Register("CamelCase", camelCaseConvention, type => true); 
A seguinte classe Comment modela os documentos na collection sample_mflix.comments:
public class Comment {     public Guid Id { get; set; }         []     public Guid MovieId { get; set; }          public string Text { get; set; } } 
Para usar o driver MongoDB .NET/C# para adicionar um estágio $lookup a um pipeline de agregação, chame o método Lookup() em um objeto PipelineDefinition.
O exemplo abaixo cria um estágio de pipeline que executa uma junção externa esquerda entre as collections movies e comments. O código une o campo Id de cada documento Movie ao campo MovieId nos documentos Comment. Os comentários de cada filme são armazenados em um campo chamado Comments em cada documento Movie .
var commentCollection = client     .GetDatabase("aggregation_examples")     .GetCollection<Comment>("comments"); var pipeline = new EmptyPipelineDefinition<Movie>()     .Lookup<Movie, Movie, Comment, Movie>(         foreignCollection: commentCollection,         localField: m => m.Id,         foreignField: c => c.MovieId,         @as: m => m.Comments); 
Os exemplos do Node.js nesta página utilizam o banco de dados do sample_mflix a partir dos conjuntos de dados de amostra do Atlas. Para saber como criar um cluster gratuito do MongoDB Atlas e carregar os conjuntos de dados de exemplo, consulte Introdução na documentação do driver do MongoDB Node.js
Para usar o driver Node.js do MongoDB para adicionar um estágio $lookup a um pipeline de agregação , use o operador $lookup em um objeto de pipeline.
O exemplo a seguir cria um estágio de pipeline que executa uma junção externa esquerda entre as coleções movies e comments. O código conecta o campo _id de cada documento movie ao campo movie_id nos documentos comment. O campo comments armazena os comentários de cada filme em cada documento movie. O exemplo em seguida executa o pipeline de agregação:
const pipeline = [   {     $lookup: {       from: "comments",       localField: "_id",       foreignField: "movie_id",       as: "comments"     }   } ]; const cursor = collection.aggregate(pipeline); return cursor;