前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >mongodb aggregate (聚合查询)联表 node+nest.js +monoose .js实现

mongodb aggregate (聚合查询)联表 node+nest.js +monoose .js实现

原创
作者头像
Jacky-易小天
修改2024-02-22 14:18:37
3522
修改2024-02-22 14:18:37
举报
文章被收录于专栏:mongodb

mongodb aggregate (聚合查询)联表 node+nest.js +monoose .js实现

联表使用的场景

mongodb的curd(增删改查)操作比较简单,但是开发者在开发过程中肯定是不够用的,如果遇到很复杂的查询操作,只查询单个表(mongodb中的集合,本人习惯称为表,以下不在赘述)是不能满足业务需求的,所以可能会连接外部表,或者查询本表之后经过分组,转化之后的临时表。或者连接外部表格链接后产生的临时表。以上这些case(时候)将会使用到本教程。

废话不多说,上代码

1. 要查询的结果是这样式的

代码语言:ts
复制
//mongodb 连表后查询文档结构 
{
    "_id": {
      "$oid": "65d2d0c0434057a3419404be"
    },
    "token": "6f9d245c-8b78-49fe-81f2-3ec71a6dc121",
    "queueId": "65d2cefd8947df31245a4599",
    "queue": {
      "id": "65d2cefd8947df31245a4599",
      "branchCode": "12345",
      "sessionId": "65d2cefd8947df31245a4569",
      "session": {
        "id": "65d2cefd8947df31245a4569",
        "branchCode": "12345",
        "nameEn": "Breakfast",
        "nameTc": "早市",
        "nameSc": "早市",
        "onlineStart": "0800",
        "onlineEnd": "1200",
        "start": "0800",
        "end": "1200",
        "branchId": "65d2cefd8947df31245a455a",
        "branch": {
          "id": "65d2cefd8947df31245a455a",
          "branchCode": "12345",
          "branchIp": null,
          "status": 1,
          "onlineStatus": 0,
          "createdAt": {
            "$date": "2024-02-19T03:46:05.006Z"
          },
          "updatedAt": {
            "$date": "2024-02-19T03:46:05.006Z"
          },
          "kioskStatus": 0,
          "kioskPrinterStatus": 0,
          "kioskScannerStatus": 0,
          "adminStatus": 0,
          "adminPrinterStatus": 0,
          "adminScannerStatus": 0,
          "callDisplayStatus": 0,
          "offlineStatus": 0,
          "branchServerStatus": 0,
          "brandId": "65d2cefc8947df31245a4554",
        }
      },
      "pplFrom": 1,
      "pplTo": 4,
      "prefix": "A",
      "current": 0,
      "last": 0,
      "vipLast": 0,
      "syncToCloud": 0,
    },
    "referenceSource": "12c3dacb",
    "referenceId": "121345caaa",
    "ticketNumber": "A1",
    "phone": "27259654",
    "type": 0,
    "status": 0,
    "ivrsStatus": 0,
    "ivrsRetry": 0,
    "blastStatus": 0,
    "blastRetry": 0,
    "apiVersion": 2,
    "lang": "TC",
    "platform": 1,
    "cancelRetry": 0,
    "called": 0,
    "createdAt": {
      "$date": "2024-02-19T03:53:36.661Z"
    },
    "updatedAt": {
      "$date": "2024-02-19T03:53:36.661Z"
    },
    "syncToCloud": 0,
    "tableSize": 4,
    "expiryDatetime": {
      "$date": "2024-02-20T03:53:36.661Z"
    },
    "id": "65d2d0c0434057a3419404be",
    "__v": 0
  }

2.需要什么样的表结构呢?

表一

代码语言:ts
复制
//mongodb ticket 表 文档结构 
{
    "_id": {
      "$oid": "65d2d0c0434057a3419404be"
    },
    "token": "6f9d245c-8b78-49fe-81f2-3ec71a6dc121",
    "queueId": "65d2cefd8947df31245a4599",
    "queue": {
      "id": "65d2cefd8947df31245a4599",
      "branchCode": "12345",
      "sessionId": "65d2cefd8947df31245a4569",
      "session": {
        "id": "65d2cefd8947df31245a4569",
        "branchCode": "12345",
        "nameEn": "Breakfast",
        "nameTc": "早市",
        "nameSc": "早市",
        "onlineStart": "0800",
        "onlineEnd": "1200",
        "start": "0800",
        "end": "1200",
        "branchId": "65d2cefd8947df31245a455a",
      },
      "pplFrom": 1,
      "pplTo": 4,
      "prefix": "A",
      "current": 0,
      "last": 0,
      "vipLast": 0,
      "syncToCloud": 0,
    },
    "referenceSource": "12c3dacb",
    "referenceId": "121345caaa",
    "ticketNumber": "A1",
    "phone": "27259654",
    "type": 0,
    "status": 0,
    "ivrsStatus": 0,
    "ivrsRetry": 0,
    "blastStatus": 0,
    "blastRetry": 0,
    "apiVersion": 2,
    "lang": "TC",
    "platform": 1,
    "cancelRetry": 0,
    "called": 0,
    "createdAt": {
      "$date": "2024-02-19T03:53:36.661Z"
    },
    "updatedAt": {
      "$date": "2024-02-19T03:53:36.661Z"
    },
    "syncToCloud": 0,
    "tableSize": 4,
    "expiryDatetime": {
      "$date": "2024-02-20T03:53:36.661Z"
    },
    "id": "65d2d0c0434057a3419404be",
    "__v": 0
  }

表二

代码语言:ts
复制
//mongodb branch 表 文档结构 
{
  "_id": {
    "$oid": "65d2cefd8947df31245a455a"
  },
  "id": "65d2cefd8947df31245a455a",
  "branchCode": "12345",
  "branchIp": null,
  "status": 1,
  "onlineStatus": 0,
  "createdAt": {
    "$date": "2024-02-19T03:46:05.006Z"
  },
  "updatedAt": {
    "$date": "2024-02-19T03:46:05.006Z"
  },
  "kioskStatus": 0,
  "kioskPrinterStatus": 0,
  "kioskScannerStatus": 0,
  "adminStatus": 0,
  "adminPrinterStatus": 0,
  "adminScannerStatus": 0,
  "callDisplayStatus": 0,
  "offlineStatus": 0,
  "branchServerStatus": 0,
  "
}

2. 那我们该如何实现呢?

案例一 localField-foreignField

代码语言:javascript
复制
let pipeline=[
      {
        $lookup:{
          from:'branch',//外部表、临时表的名称
          localField:"queue.session.branchCode",//xxxxModel映射表的代码的字段
          foreignField:"branchCode",//branc表的字段
          as:'branch'//将连接的表输出为某字段
        }
      },
      {
        $project:{
        "queue.session.branch":"$branch"
        }
      }
    ]
    
this.xxxxModel.aggregate(pipeline)//xxxModel 是mongose model

案例二 pipeline 方式

代码语言:ts
复制
//mongodb 的aggregate 的聚合实现方式方式
// 采用的pipeline 方式,可以实现更加复杂的逻辑,比如增加分组、多次match 等方式。
let pipeline=[
      {
        $lookup:{
          from:'branch',//外部表、临时表的名称
          let: { branchCode: "$session.branchCode"},
          pipeline: [ {
              $match: {
                $expr: {
                    $and: [
                      { $eq: [ "$$branchCode", "$branchCode" ] },
                    ]
                }
              }
          } ],
          as:'branch'//将连接的表输出为某字段
        }
      }]
  this.ticketModel.aggregate(pipeline)//ticketModel 是mongose model

案例二

代码语言:ts
复制
/mongodb 的aggregate 的聚合实现方式方式
// 注释的内容是采用的pineline 方式,可以实现更加复杂的逻辑,比如增加分组、多次match 等方式。
let pipeline=[
  {
    $lookup:{
      from:'branch',//外部表、临时表的名称
      let: { branchCode: "$session.branchCode"},
      pipeline: [ {
          $match: {
            $expr: {
                $and: [
                  { $eq: [ "$$branchCode", "$branchCode" ] },
                ]
            }
          }
      } ],
      as:'branch'//将连接的表输出为某字段
    }
  },
  {
    $project:{
    "queue.session.branch":"$branch"
    }
  }
]
this.ticketModel.aggregate(pipeline)//ticketModel 是mongose model

案例三、连接自身

代码语言:ts
复制
//mongodb 连表后查询文档结构 
{
    
  "dateTime":"20-02-2024",
  "onlineTickets":5,
  "offlineTickets":1,
  "checkedInTickets":0
}

查询实现

代码语言:ts
复制
let =pipeline=[
  {
    '$lookup': {
      'from': 'ticket', 
      'let': {
        'date': {
          '$dateToString': {
            'format': '%d-%m-%Y', 
            'date': '$createdAt'
          }
        }
      }, 
      'pipeline': [
        {
          '$match': {
            '$and': [
               {
                'status': {
                  '$ne': 5
                }
              }
            ]
          }
        }, {
          '$addFields': {
            'fliteDate': {
              '$dateToString': {
                'format': '%d-%m-%Y', 
                'date': '$createdAt'
              }
            }
          }
        }, {
          '$group': {
            '_id': '$fliteDate', 
            'totalSum': {
              '$sum': 1
            }
          }
        }, {
          '$match': {
            '$expr': {
              '$eq': [
                '$_id', '$$date'
              ]
            }
          }
        }
      ], 
      'as': 'onlineTicket'
    }
  }, {
    '$lookup': {
      'from': 'ticket', 
      'let': {
        'date': {
          '$dateToString': {
            'format': '%d-%m-%Y', 
            'date': '$createdAt'
          }
        }
      }, 
      'pipeline': [
        {
          '$match': {
            '$and': [
               {
                'status': {
                  '$ne': 5
                }
              }
            ]
          }
        }, {
          '$addFields': {
            'fliteDate': {
              '$dateToString': {
                'format': '%d-%m-%Y', 
                'date': '$createdAt'
              }
            }
          }
        }, {
          '$group': {
            '_id': '$fliteDate', 
            'totalSum': {
              '$sum': 1
            }
          }
        }, {
          '$match': {
            '$expr': {
              '$eq': [
                '$_id', '$$date'
              ]
            }
          }
        }
      ], 
      'as': 'offlineTicket'
    }
  }, {
    '$lookup': {
      'from': 'ticket', 
      'let': {
        'date': {
          '$dateToString': {
            'format': '%d-%m-%Y', 
            'date': '$createdAt'
          }
        }
      }, 
      'pipeline': [
        {
          '$match': {
            '$and': [
              {
                'status': 3
              }
            ]
          }
        }, {
          '$addFields': {
            'fliteDate': {
              '$dateToString': {
                'format': '%d-%m-%Y', 
                'date': '$createdAt'
              }
            }
          }
        }, {
          '$group': {
            '_id': '$fliteDate', 
            'totalSum': {
              '$sum': 1
            }
          }
        }, {
          '$match': {
            '$expr': {
              '$eq': [
                '$_id', '$$date'
              ]
            }
          }
        }
      ], 
      'as': 'checkedInTicket'
    }
  }, {
    '$addFields': {
      'onlineTickets': {
        '$ifNull': [
          {
            '$arrayElemAt': [
              '$onlineTicket.totalSum', 0
            ]
          }, 0
        ]
      }, 
      'offlineTickets': {
        '$ifNull': [
          {
            '$arrayElemAt': [
              '$offlineTicket.totalSum', 0
            ]
          }, 0
        ]
      }, 
      'checkedInTickets': {
        '$ifNull': [
          {
            '$arrayElemAt': [
              '$checkedInTicket.totalSum', 0
            ]
          }, 0
        ]
      }
    }
  }, {
    '$unset': [
      'onlineTicket', 'offlineTicket', 'checkedInTicket'
    ]
  }, {
    '$group': {
      '_id': {
        'dateTime': {
          '$dateToString': {
            'format': '%d-%m-%Y', 
            'date': '$createdAt'
          }
        }, 
        'onlineTickets': '$onlineTickets', 
        'offlineTickets': '$offlineTickets', 
        'checkedInTickets': '$checkedInTickets', 
      }
    }
  }, {
    '$project': {
      '_id': 0, 
      'dateTime': '$_id.dateTime', 
      'onlineTickets': '$_id.onlineTickets', 
      'offlineTickets': '$_id.offlineTickets', 
      'checkedInTickets': '$_id.checkedInTickets', 
    }
  }, {
    '$sort': {
      'dateTime': -1
    }
  }
]
this.ticketModel.aggregate(pipeline)//ticketModel 是mongose model

包括但不限于这些场景,如有其他应用场景,和疑问欢迎评论区留言

我正在参与2024腾讯技术创作特训营第五期有奖征文,快来和我瓜分大奖!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • mongodb aggregate (聚合查询)联表 node+nest.js +monoose .js实现
  • 联表使用的场景
    • 废话不多说,上代码
      • 1. 要查询的结果是这样式的
        • 2.需要什么样的表结构呢?
          • 2. 那我们该如何实现呢?
            • 案例一 localField-foreignField
              • 案例二 pipeline 方式
                • 案例三、连接自身
                • 包括但不限于这些场景,如有其他应用场景,和疑问欢迎评论区留言
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档