mongodb节点驱动程序中的$sum聚合

Posted

技术标签:

【中文标题】mongodb节点驱动程序中的$sum聚合【英文标题】:$sum aggregation in mongodb nodej driver 【发布时间】:2020-05-18 22:46:40 【问题描述】:

集合 1:管理员


    "_id" : ObjectId("5e27fd3da42d441fe8a89580"),
    "mappedcustomers": [
        ObjectId("5e2555783405363bc4bf86c5"),
        ObjectId("5e2555783405363bc4bf86c0"),
        ObjectId("5e2555783405363bc4bf86c4")
    ],
    "phoneNo" : 9897654358,
    "name" : "acdbcs"

集合 2:productOrders

Tt有很多文档,我们关心的只是:

    "productOrderedForDate" : ISODate("2020-02-04T18:30:00Z")[明天订单]。 "productOrderedForDate" : ISODate("2020-02-28T18:30:00Z")[上周下单]
[
    
        "_id": ObjectId("5e27f998a42d441fe8a8957f"),
        "authorized": false,
        "orderCreatedBy": ObjectId("5e2555783405363bc4bf86c4"), // one of the mappedCustomer
        "productOrderedForDate": ISODate("2020-02-04T18:30:00Z"),// tomorrow Order
        "order": [
            "_id": ObjectId("5e26be2cc13b7149d0a95110"),
            "productName": "Cups",
            "productCode": "CICE1",
            "size R": 21,
            "size L": 16
        ,
            
                "_id": ObjectId("5e26be2cc13b7149d0a9510f"),
                "productName": "Bottles",
                "productCode": "BTCE1",
                "size R": 12,
                "size L": 3
            ]
    ,
    
        "_id": ObjectId("5e26be2cc13b7149d0b90752b"),
        "authorized": false,
        "orderCreatedBy": ObjectId("5e2555783405363bc4bf86c0"),// another mappedCustomer
        "productOrderedForDate": ISODate("2020-02-04T18:30:00Z"),// tomorrow Order
        "order": [
            "_id": ObjectId("5e26be2cc13b7149d0a87230"),
            "productName": "Cups",
            "productCode": "CICE1",
            "size R": 9,
            "size L": 7
        ,
            
                "_id": ObjectId("5e26be2cc13b7149d0a8560e"),
                "productName": "Bottles",
                "productCode": "BTCE1",
                "size R": 3,
                "size L": 11
            ]

    ,
    
        "_id": ObjectId("5e26be2cc13b7149d0b9876f"),
        "authorized": true,
        "orderCreatedBy": ObjectId("5e2555783405363bc4bf86c4"), // one of the mappedCustomer
        "productOrderedForDate": ISODate("2020-01-28T18:30:00Z"),// lastWeek order 
        "order": [
            "_id": ObjectId("5e26be2cc13b7149d0a54220"),
            "productName": "Cups",
            "productCode": "CICE1",
            "size R": 2,
            "size L": 6
        ,
            
                "_id": ObjectId("5e26be2cc13b7149d0a6520e"),
                "productName": "Bottles",
                "productCode": "BTCE1",
                "size R": 8,
                "size L": 16
            ]

    ,
    

        "_id": ObjectId("5e78f998a42d441fe898765d"),
        "authorized": true,
        "orderCreatedBy": ObjectId("5e2555783405363bc4bf86c0"), // another mappedCustomer
        "productOrderedForDate": ISODate("2020-01-28T18:30:00Z"),// lastWeek order 
        "order": [
            "_id": ObjectId("5e26be2cc13b7149d0a87230"),
            "productName": "Cups",
            "productCode": "CICE1",
            "size R": 26,
            "size L": 19
        ,
            
                "_id": ObjectId("5e26be2cc13b7149d0a8560f"),
                "productName": "Bottles",
                "productCode": "BTCE1",
                "size R": 4,
                "size L": 5
            ]
    
]

这是我已经尝试过的并且已经能够展开所有 mappedCustomers 并且据此我已经能够在下面的订单集合中找到他们创建的订单是聚合管道

db.admin.aggregate([
    
        $match: 
            _id: ObjectId("5e27fd3da42d441fe8a89580")
        
    ,
    
        $lookup:
            
                from: 'admin',
                localField: 'mappedCustomers',
                foreignField: '_id',
                as: 'mappedCustomers'
            
    ,
    
        $unwind: '$mappedCustomers'
    ,
    
        $replaceRoot: newRoot: "$mappedCustomers"
    ,
    
        $lookup:
            
                from: "orders",
                let: mappedCustomersId: "$_id",
                pipeline: [
                    
                        $match: 
                            $expr: $eq: ["$orderCreatedBy", "$$mappedCustomersId"],
                            '$or': [
                                
                                    'orderCreatedOn': ISODate("2020-02-04T18:30:00Z")
                                , 
                                    'orderCreatedOn': ISODate("2020-01-28T18:30:00Z")
                                ]
                        
                    ],
                as: "orders"
            
    , 
        $unwind: "orders"
    
])

我的问题是,我需要显示所有mappedCustomers 的所有size Rsize L 的总和,而productCode 在该管理员下映射为明天的日期和上一周的日期,即

预期输出:


    orders : [
        
            "productOrderedForDate": ISODate("2020-02-04T18:30:00Z"),
            "productName": "Cups",
            "productCode": "CICE1",
            "size R": 30,
            "size L": 23,
            "lastWeek": [
                "productOrderedForDate": ISODate("2020-01-28T18:30:00Z"),
                "size R": 28,
                "size L": 25,
            ]
        , 
            "productOrderedForDate": ISODate("2020-02-04T18:30:00Z"),
            "productName": "Bottles",
            "productCode": "BTCE1",
            "size R": 15,
            "size L": 14,
            "lastWeek": [
                "productOrderedForDate": ISODate("2020-01-28T18:30:00Z"),
                "size R": 12,
                "size L": 21,
            ]
        
    ]

回顾一下: 1. 我会从req.body 获取管理员id。 2.我会找到所有映射到mappedCustomers的客户。 3. 我将从orders 集合中查找mappedCustomers 为所需日期创建的订单。 4. 我需要将所有size Rsize L 分组。

我设法做到了 1,2,3,但我无法为 4 和 5 产生所需的结果。请看一下并告诉我是否可以实现。

我已经看过this 的帖子,但我无法让它工作。

【问题讨论】:

【参考方案1】:

试试这个:

db.admin.aggregate([
  
    $match: 
      _id: ObjectId("5e27fd3da42d441fe8a89580")
    
  ,
  
    $lookup: 
      from: "admin",
      localField: "mappedcustomers",
      foreignField: "_id",
      as: "mappedcustomers"
    
  ,
  
    $unwind: "$mappedcustomers"
  ,
  
    $replaceRoot: 
      newRoot: "$mappedcustomers"
    
  ,
  
    $lookup: 
      from: "orders",
      let: 
        mappedCustomersId: "$_id"
      ,
      pipeline: [
        
          $match: 
            $expr: 
              $eq: [
                "$orderCreatedBy",
                "$$mappedCustomersId"
              ]
            ,
            "$or": [
              
                "productOrderedForDate": ISODate("2020-02-04T18:30:00Z")
              ,
              
                "productOrderedForDate": ISODate("2020-01-28T18:30:00Z")
              
            ]
          
        
      ],
      as: "orders"
    
  ,
  
    $unwind: "$orders"
  ,
  
    $unwind: "$orders.order"
  ,
  
    $group: 
      _id: "$orders.order.productCode",
      orders: 
        $push: 
          productOrderedForDate: "$orders.productOrderedForDate",
          productName: "$orders.order.productName",
          productCode: "$orders.order.productCode",
          "size R": "$orders.order.size R",
          "size L": "$orders.order.size L"
        
      
    
  ,
  
    $project: 
      thisweek: 
        $reduce: 
          input: 
            $filter: 
              input: "$orders",
              cond: 
                $eq: [
                  "$$this.productOrderedForDate",
                  ISODate("2020-02-04T18:30:00Z")
                ]
              
            
          ,
          initialValue: 
            "size R": 0,
            "size L": 0
          ,
          in: 
            productOrderedForDate: "$$this.productOrderedForDate",
            "productName": "$$this.productName",
            "productCode": "$$this.productCode",
            "size R": 
              $add: [
                "$$value.size R",
                "$$this.size R"
              ]
            ,
            "size L": 
              $add: [
                "$$value.size L",
                "$$this.size L"
              ]
            
          
        
      ,
      lastWeek: 
        $reduce: 
          input: 
            $filter: 
              input: "$orders",
              cond: 
                $eq: [
                  "$$this.productOrderedForDate",
                  ISODate("2020-01-28T18:30:00Z")
                ]
              
            
          ,
          initialValue: 
            "size R": 0,
            "size L": 0
          ,
          in: 
            productOrderedForDate: "$$this.productOrderedForDate",
            "size R": 
              $add: [
                "$$value.size R",
                "$$this.size R"
              ]
            ,
            "size L": 
              $add: [
                "$$value.size L",
                "$$this.size L"
              ]
            
          
        
      
    
  ,
  
    $group: 
      _id: null,
      orders: 
        $push: 
          $mergeObjects: [
            "$thisweek",
            
              "lastWeek": [
                "$lastWeek"
              ]
            
          ]
        
      
    
  ,
  
    $unset: "_id"
  
])

MongoPlayground

【讨论】:

以上是关于mongodb节点驱动程序中的$sum聚合的主要内容,如果未能解决你的问题,请参考以下文章

mongoDB,带有 $sum 和 $count 的 mongoose 聚合查询

mongoDB,带有 $sum 和 $count 的 mongoose 聚合查询

MongoDB 中的计算

《MongoDB入门教程》第23篇 聚合统计之$sum表达式

《MongoDB入门教程》第23篇 聚合统计之$sum表达式

MongoDB:聚合aggregate