Mongo-汇总组查找值

时间:2020-08-21 13:30:18

标签: mongodb mongoose

我正在尝试汇总查找中列出的值。我有2个收藏集:

订阅(伪代码)

{
   _id,
   purchaseDate: Date,
   wholesalePrice: Number,
   purchasePrice: Number,
   retailPrice: Number,
   userID: String,
}

付款

{
   _id,
   statementMonth: String, // e.g. 2020-08 (same as grouped id in Subscriptions)
   paymentDate: Date,
   userID: String,
   amountPaid
}

用户将需要在月底转移利润率值。因此,我想为Statements创建一个输出。这些将把所有“订阅和付款”归为每月记录,并汇总其中的所有数据。我已经设法创建了第一组中的所有内容,但是一旦我进行查询以获取“付款”详细信息,一切似乎都将失败。

这是我当前的管道

    {
        "$match": {
            "userID": [provided UserID]
        }
    }, 
    {
        "$group": {
            "_id": {
                "$dateToString": {
                    "format": "%Y-%m",
                    "date": "$purchaseDate"
                }
            },
            "totalWholesalePrice": {
                "$sum": "$wholesalePrice"
            },
            "totalPurchasePrice": {
                "$sum": "$purchasePrice"
            },
            "count": {
                "$sum": 1.0
            }
        }
    }, 
    {
        "$addFields": {
            "totalAmountDue": {
                "$subtract": [
                    "$totalPurchasePrice",
                    "$totalWholesalePrice"
                ]
            }
        }
    }, 
    {
        "$lookup": {
            "from": "transactions",
            "localField": "_id",
            "foreignField": "statementMonth",
            "as": "transactions"
        }
    }, 
    {
        "$unwind": {
            "path": "$transactions",
            "preserveNullAndEmptyArrays": true
        }
    }, 
    {
        "$sort": {
            "_id": -1.0
        }
    }

如果有2笔交易,它将返回2条记录:

{ 
    "_id" : "2020-08", 
    "totalWholesalePrice" : NumberInt(89), 
    "totalPurchasePrice" : 135.55, 
    "count" : 8.0, 
    "totalAmountDue" : 46.55, 
    "transactions" : {
        "_id" : ObjectId("5f3faf2216d7a517bc51bfae"), 
        "date" : ISODate("2020-04-20T11:23:40.284+0000"), 
        "statementMonth" : "2020-08", 
        "merchant" : "M1268360", 
        "amountPaid" : "40"
    }   
}

{ 
    "_id" : "2020-08", 
    "totalWholesalePrice" : NumberInt(89), 
    "totalPurchasePrice" : 135.55, 
    "count" : 8.0, 
    "totalAmountDue" : 46.55, 
    "transactions" : {
        "_id" : ObjectId("5f3fc13f16d7a517bc51c047"), 
        "date" : ISODate("2020-04-20T11:23:40.284+0000"), 
        "statementMonth" : "2020-08", 
        "merchant" : "M1268360", 
        "amountPaid" : "2"
    }
}

我希望最终的JSON是:

    { 
        "_id" : "2020-08", 
        "totalWholesalePrice" : NumberInt(89), 
        "totalPurchasePrice" : 135.55, 
        "count" : 8.0, 
        "totalAmountDue" : 46.55, 
        "transactions" : [{
            "_id" : ObjectId("5f3faf2216d7a517bc51bfae"), 
            "date" : ISODate("2020-04-20T11:23:40.284+0000"), 
            "statementMonth" : "2020-08", 
            "merchant" : "M1268360", 
            "amountPaid" : "40"
        } 
        {
            "_id" : ObjectId("5f3fc13f16d7a517bc51c047"), 
            "date" : ISODate("2020-04-20T11:23:40.284+0000"), 
            "statementMonth" : "2020-08", 
            "merchant" : "M1268360", 
            "amountPaid" : "2"
        }],
        "totalPaid" : 42, 
        "totalBalance" : 4.55, 
    }

1 个答案:

答案 0 :(得分:1)

您需要再添加一条管道

db.collection.aggregate([
  {
    $group: {
      "_id": "$id",
      "transactions": { //Grouping transactions together
        "$addToSet": "$transactions"
      },
      "totalWholesalePrice": {//As all values are unique getting the first
        "$first": "$totalWholesalePrice"
      }
      //Similarly add the needed fields - use $first, $addToSet
    }
  }
])

playground

要获取总计:

db.collection.aggregate([
  {
    $group: {
      "_id": "$id",
      "transactions": {
        "$addToSet": "$transactions"
      },
      "totalWholesalePrice": {
        "$first": "$totalWholesalePrice"
      },
      "totalAmountPaid": {
        $sum: {
          $toInt: "$transactions.amountPaid" //you stored as string, convert to appropriate type
        }
      }
    }
  }
])

playground