$lookup - 表关联查询


1. 主要功能

是将每个输入待处理的文档,经过$lookup 阶段的处理,输出的新文档中会包含一个新生成的数组列(户名可根据需要命名新key的名字 )。数组列存放的数据 是 来自 被Join 集合的适配文档,如果没有,集合为空(即 为[ ] )

2. 基本语法

  1. 1. {
  2. 2. $lookup:
  3. 3. {
  4. 4. from: <collection to join>,
  5. 5. localField: <field from the input documents>,
  6. 6. foreignField: <field from the documents of the "from" collection>,
  7. 7. as: <output array field>
  8. 8. }
  9. 9. }

3. 语法的解释说明

语法值 解释说明
from 同一个数据库下等待被Join的集合。
localField 源集合中的match值,如果输入的集合中,某文档没有 localField这个Key(Field),在处理的过程中,会默认为此文档含有 localField:null的键值对。
foreignField 待Join的集合的match值,如果待Join的集合中,文档没有foreignField值,在处理的过程中,会默认为此文档含有 foreignField:null的键值对。
as 为输出文档的新增值命名。如果输入的集合中已存在该值,则会覆盖掉,

(注:null = null 此为真)

其语法功能类似于下面的伪SQL语句:

  1. 1. SELECT *, <output array field>
  2. 2. FROM collection
  3. 3. WHERE <output array field> IN (SELECT *
  4. 4. FROM <collection to join>
  5. 5. WHERE <foreignField>= <collection.localField>);

4. 实例


准备数据
  • 源表sales_1
  1. db.getCollection('sales_1').insertMany([
  2. { "_id" : 2, "item2": 2, "as1": 2, "as2": 2},
  3. { "_id" : 5, "item2": 5, "as1": 5, "as2": 5}
  4. ])
  • 被join集合sales_2
  1. db.getCollection('sales_2').insertMany([
  2. { "_id" : 1, "item" : "1", "price" : 10, "quantity" : 2},
  3. { "_id" : 2, "item" : "2", "price" : 20, "quantity" : 1},
  4. { "_id" : 3, "item" : "3", "price" : 5, "quantity" : 10},
  5. { "_id" : 4, "item" : "4", "price" : 5, "quantity" : 20},
  6. { "_id" : 5, "item" : "5", "price" : 10, "quantity" : 10}
  7. ])
  • 查询源表**item的价格 **price
  1. db.sales_1.aggregate([
  2. {
  3. $lookup:
  4. {
  5. from: "sales_2", // 集合sales_2的名称
  6. localField: "item", // 集合sales_1中的match
  7. foreignField: "item2", // 集合sales_2match
  8. as: "sales_2_as_arr" // 为输出文档的新增值命名
  9. }
  10. }
  11. ])

( 注意: localField和 foreignField 对应的Key 定义 比较列)

转自 && 感谢: https://blog.csdn.net/cxu123321/article/details/99619877?ops_request_misc=&request_id=&biz_id=102&utm_term=$lookup&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-6-.nonecase&spm=1018.2226.3001.4187