查找功能使您能够从数据库上的“已联接”集合中过滤文档,以便更轻松地处理相互关联的信息。
在MongoDB联合数据库实例中,您可以使用$lookup 对来自同一数据库或不同数据库的分片的或未分片集合执行左外连接。您可以应用Atlas、$lookup AWS S3 以及HTTP或 HTTPS 上的任何联合数据存储上的集合。
注意
对于分片的集合,$lookup 仅适用于运行MongoDB 及更高版本的Atlas集群。5.1
语法
MongoDB服务器手册中描述了$lookup语法。
在 Data Federation 中, $lookup中的from字段采用以下备用语法。 这允许您指定一个包含可选的数据库名称和必需的collection名称的对象:
{ $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 字段对象
示例
假设存在三个名为sourceDB1 、 sourceDB2和sourceDB3的数据库,其中包含以下集合:
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 } ])
以下示例使用$lookup聚合阶段将一个集合中的文档与其他数据库中该集合中的文档连接起来。
基本示例
以下针对sourceDB1.orders集合的聚合操作使用orders sourceDB2.catalog orders的item字段以及 sku catalog集合:
db.getSiblingDB("sourceDB1").orders.aggregate( { $lookup: { from: { db: "sourceDB2", coll: "catalog" }, localField: "item", foreignField: "sku", as: "inventory_docs" } } )
嵌套示例
以下针对 集合的聚合操作使用sourceDB1.orders orders集合中的 字段将sourceDB2.catalog 集合中的文档与 集合中的文档以及sourceDB3.warehouses itemorders集合中的文档连接起来,sku 集合中的catalog 字段,以及stock_item instock集合中的 和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" }, }, ] )