Lookups te permite filtrar documentos de colecciones "unidas" en tus bases de datos para un procesamiento más sencillo de información correlacionada.
En las instancias federadas de bases de datos de MongoDB, puedes usar $lookup para realizar una unión externa izquierda de una colección particionada o no particionada de la misma base de datos o de una base de datos diferente. Puedes aplicar $lookup a las colecciones de cualquiera de tus almacenes de datos federados en Atlas, AWS S3, y HTTP o HTTPS.
Nota
Para colecciones particionadas, $lookup solo está disponible en clústeres Atlas que ejecutan MongoDB 5.1 o versiones posteriores.
Sintaxis
La sintaxis $lookup se describe en el manual del servidor de MongoDB.
En Data Federation, el campo from en $lookup tiene la siguiente sintaxis alternativa. Esto te permite especificar un objeto que contiene un nombre de base de datos opcional y un nombre de colección obligatorio:
{ $lookup: { localField: "<fieldName>", from: <collection-to-join>|{db: <db>, coll: <collection-to-join>}, foreignField: "<fieldName>", as: "<output-array-field>", } }
{ $lookup: { from: <collection to join>|{db: <db>, coll: <collection-to-join>}, let: { <var_1>: <expression>, …, <var_n>: <expression> }, pipeline: [ <pipeline to execute on the collection to join> ], as: <output array field> } }
from Objeto de campo
Campo | Tipo | Descripción | Necesidad |
|---|---|---|---|
| string | El nombre de la base de datos. Si se especifica un nombre de base de datos, Data Federation lee los datos de la colección en la base de datos especificada. Si especifica un nombre de base de datos que difiere de la base de datos sobre la cual se está ejecutando el comando, todas las etapas anidadas de $lookup deben también especificar este nombre de base de datos. Si no se especifica un nombre de base de datos dentro de una etapa de $lookup, las colecciones en la etapa heredarán el nombre de base de datos especificado en la etapa $lookup principal más cercana, si existe, o el nombre de la base de datos sobre la cual se está ejecutando el comando. | Condicional |
| string | El nombre de la colección. | Requerido |
Ejemplos
Suponga que hay tres bases de datos llamadas sourceDB1, sourceDB2, y sourceDB3 con las siguientes colecciones:
db.orders.insertMany([ { "_id" : 1, "item" : "almonds", "price" : 12, "quantity" : 2 }, { "_id" : 2, "item" : "pecans", "price" : 20, "quantity" : 1 }, { "_id" : 3 } ])
db.catalog.insertMany([ { "_id" : 1, "sku" : "almonds", "description": "product 1" }, { "_id" : 2, "sku" : "bread", "description": "product 2" }, { "_id" : 3, "sku" : "cashews", "description": "product 3" }, { "_id" : 4, "sku" : "pecans", "description": "product 4" }, { "_id" : 5, "sku": null, "description": "Incomplete" }, { "_id" : 6 } ])
db.warehouses.insertMany([ { "_id" : 1, "stock_item" : "almonds", "warehouse": "A", "instock" : 120 }, { "_id" : 2, "stock_item" : "pecans", "warehouse": "A", "instock" : 70 }, { "_id" : 3, "stock_item" : "cashews", "warehouse": "B", "instock" : 60 }, { "_id" : 4, "stock_item" : "bread", "warehouse": "B", "instock" : 80 }, { "_id" : 5, "stock_item" : "cookies", "warehouse": "A", "instock" : 80 } ])
Los siguientes ejemplos utilizan la etapa de agregación $lookup para unir documentos de una colección con documentos de otras bases de datos.
Ejemplo básico
La siguiente operación de agregación en la colección sourceDB1.orders une los documentos de la colección orders con los documentos de la colección sourceDB2.catalog utilizando el campo item de la colección orders y el campo sku de la colección catalog:
db.getSiblingDB("sourceDB1").orders.aggregate( { $lookup: { from: { db: "sourceDB2", coll: "catalog" }, localField: "item", foreignField: "sku", as: "inventory_docs" } } )
Ejemplo anidado
La siguiente operación de agregación en la colección sourceDB1.orders une los documentos de la colección orders con los documentos de la colección sourceDB2.catalog y los documentos de la colección sourceDB3.warehouses utilizando el campo item de la colección orders, el campo sku de la colección catalog y los campos stock_item y instock de la colección warehouses:
db.getSiblingDB("sourceDB1").orders.aggregate( [ { $lookup: { from: db: "sourceDB2", coll: "catalog", let: { "order_sku": "$item" }, pipeline: [ { $match: { $expr: { $eq: ["$sku", "$$order_sku"] } } }, { $lookup: { from: db: "sourceDB3", coll: "warehouses", pipeline: [ { $match: { $expr:{ $eq : ["$stock_item", "$$order_sku"] } } }, { $project : { "instock": 1, "_id": 0} } ], as: "wh" } }, { "$unwind": "$wh" }, { $project : { "description": 1, "instock": "$wh.instock", "_id": 0} } ], as: "inventory" }, }, ] )