史上最详细MongoDB多表/N表连接查询配置详解

MongoDB多表连接查询,Mongoose聚合查询

// 依赖模块:mongoose
npm i -S mongoose

简介

一种对MongoDB进行使用多表连接查询的函数

使用方式及字段介绍

model.aggregate(<ConditionSetting>).then(<resolveFunction>).catch(<rejectFunction>)

其中

  • ConditionSetting为操作设置
  • resolveFunction为执行成功回调函数,可设置形参接收查询结果result
  • rejectFunction为执行失败回调函数,可设置形参接收错误报告err

输入的变量值ConditionSetting根据需求可以有不同的输入,个人认为最常见的输入为:

[
    
    {$lookup},   // 多表连接配置
    {$unwind},   // 查询结果的字段的拆分
    {$addFields},
    {$project},
    {$match},
    {$sort},
    {$limit},
    {$skip},
    [{$count}]
]

因此本次只就以上字段进行解释:

  • $lookup

    • 输入值:

      { $lookup: {
          from:<String>, 
          localField:<String>, 
          foreignField:<String>, 
          as:<String>
      } }
      
    • 含义解释:对表连接的配置,类似于sql中的join操作,其字段必有:

      • from : 要连接的目标表,类似于sql中的join

      • localField :作为连接参照的本表字段

      • foreignField :作为连接参照的目标表字段,localField和foreignField类似sql多表连接中join后的等值设置—> select [someThing] from [table] join [targetTable] on localField=foreignField

      • as:当连接查询查询出来之后,外表的查询结果会在本表查询结果中开辟一个新的字段进行存储,而字段名就是这个字段设置的,只有一个存储结果时为单独的对象字段,多个结果时为对象数组 :

        • {
              "LocalResultField":"FieldValue",
                  ···
              [valueOfAs]:[{
                  // 这里是从另一个表里匹配到的结果
                  // 注意:
                  // 这条数据有它在另一个表里全部的字段
          		// 也就相当于是只是把这个匹配到的数据直接从另一个表里搬过来了而已
                  "otherTable'sField":"FieldValue"
                  ···
              },
                           ···
              ]
          }
          
  • $unwind

    • 输入值:

      { $unwind: <String> /*这里的值和 $lookup 中 as 的值是一样的*/ }
      
    • 含义解释:对$lookup中as中的结果进行拆分操作,具体表现为:如果查询出多个数据,会将查询结果存储的数组进行拆分,使之成为多个单独对象的值:

      之前是这样的:

    • {
          "LocalResultField":"FieldValue",
              ···
          [valueOfAs]:[/*这里是一个有好多好多好多对象组合成的数组*/]
      }
      
    • 进行拆分设置后变成了这样:

      [
          {
          	"LocalResultField":"FieldValue",
              	···
          	[valueOfAs]:{/*这里是数组里的其中一个数据*/}
      	},
          {
          	"LocalResultField":"FieldValue",
              	···
          	[valueOfAs]:{/*这里是数组里的另一个数据*/}
      	},
              ···
      ]
      
  • $addFields

    • 输入值:

      {$addFields:{
          // 举例
          "aaa":"$as.bbb"
          
          // 格式
          "newFieldName":"$[value Of The As].[Original Name IN Other Table]"
      }}
      
    • 含义解释:对最终查询结果的结构进行添加新字段操作,如果原本表里没有这个字段,你又要在结果里显示这个字段,那首先要对结果进行添加新字段操作,相当于是将外来字段设置进本表查询结果中

  • $project

    • 输入值:

      {$project:{
          "field":1  // “1”表示你要将这个字段在最终结果中显示,没有“0”
          ···
      }}
      
    • 含义解释:对最终查询结果的显示操作,设置了的字段会在最终输出结果中显示,没设置的字段不会显示,这里面设置的字段必须是原本表里拥有的字段,如果原本表里没有的字段必须要先通过 $addFields 进行添加操作才能设置,类似于sql查询语句中的 select 后 from前的部分

  • $match

    • 输入值:

      {$match:{
          // 这里输入一些查询条件
          // 例子
          "aaa":"111"
          
        // 格式
          "field":"conditionValue"
      }
      }
      
    • 含义解释:查询条件,类似于sql查询语句中的where部分

  • $sort

    • 输入值:

      {$sort:{
          "field": 1/-1 //“1”表示升序排列,“-1”表示降序排列
      }}
      
    • 含义解释:对搜索结果根据选定字段进行排序

    • 注意事项:limit,skip,sort的最终执行顺序是:先sort后skip后limit

  • $limit

    • 输入值:

      {$limit:<Number>}
      
    • 含义解释:对输出的结果条目进行指定数量的限制

    • 注意事项:limit,skip,sort的最终执行顺序是:先sort后skip后limit

  • $skip

    • 输入值:

      {$skip:<Number>}
      
    • 含义解释:对输出结果跳过指定数目的数据

    • 注意事项:limit,skip,sort的最终执行顺序是:先sort后skip后limit

  • [$count]

    • 输入值:

      {$count:<String>}  
      

      当然也可以连缀调用

      model.aggregate(Condition).count(<String>)
      
    • 含义解释:在总搜索结果中插入新的字段表示对搜索结果的总条目的计数,输入的值只是为了定义这个承载计数结果的字段的名字

    • 注意事项:一旦使用了count,则最终只会输出count的计数结果而不会输出查询结果,如果既想要查询结果又想要计数结果可以使用Promise.all


最后的注意事项

以上字段的执行顺序是按顺序进行的,因此设置的字段顺序会对最终结果产生影响,例如先插入match后插入lookup的话就会先执行条件查询操作后进行表连接操作

  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
MongoDB中,$lookup操作符可以用于实现多表连接查询。它可以将两个集合中的文档进行关联,并返回一个新的文档,其中包含了两个集合中匹配的文档信息。而在进行$lookup操作之后,我们可以使用$project操作符来对查询结果进行进一步的处理,以选择需要显示的字段或者添加新的字段。 例如,假设我们有两个集合"orders"和"customers",它们的结构分别如下: orders集合: ``` { "_id": ObjectId("5f94e5c0d286db2d3ad3a71c"), "order_id": 1, "customer_id": ObjectId("5f94e5c0d286db2d3ad3a71a"), "product": "computer", "amount": 3 } ``` customers集合: ``` { "_id": ObjectId("5f94e5c0d286db2d3ad3a71a"), "name": "Tom", "age": 25, "address": "New York" } ``` 现在我们希望查询orders集合中的文档,并将其与customers集合中的文档进行关联,以获取订单对应的客户信息。我们可以使用以下的$lookup和$project操作来实现: ``` db.orders.aggregate([ { $lookup: { from: "customers", localField: "customer_id", foreignField: "_id", as: "customer_info" } }, { $project: { "order_id": 1, "product": 1, "amount": 1, "customer_name": "$customer_info.name", "customer_age": "$customer_info.age", "customer_address": "$customer_info.address" } } ]) ``` 在上述代码中,$lookup操作符用于将orders集合中的"customer_id"字段与customers集合中的"_id"字段进行关联,并将匹配的文档信息存储在一个新的字段"customer_info"中。而$project操作符则用于对查询结果进行处理,选择需要显示的字段,并添加新的字段"customer_name"、"customer_age"和"customer_address"来显示客户的姓名、年龄和地址。 参考资料: - MongoDB官方文档:$lookup - MongoDB官方文档:$project

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值