繁体   English   中英

$aggregation, $sum 在 MongoDB 中的两个集合上

[英]$aggregation, $sum on two collections in MongoDB

嗨,假设我有这两个集合

样本1:

 {
    "_id" : {
            "date" : ISODate("2020-02-11T18:30:00Z"),
            "price" : 4,
            "offer" : 0,
            "itemCode" : "A001"
            "customerId" : ObjectId("5e43de778b57693cd46859eb"),
            "sellerId" : ObjectId("5e43e5cdc11f750864f46820"),
      },
    "charges" : 168
  }
  {
    "_id" : {
            "date" : ISODate("2020-02-11T18:30:00Z"),
            "coverPrice" :5.5 ,
            "offer" : 38,
            "itemCode" : "B001"
            "customerId" : ObjectId("5e43de778b57693cd46859eb"),
            "sellerId" : ObjectId("5e43e5cdc11f750864f46820"),
    },
    "charges" : 209.5
  }

注意: sample1 的_id没有任何ObjectId()

样本2:

        {
            "paymentReceivedOnDate" : ISODate("2020-02-12T18:30:00Z"),
             "customerId" : ObjectId("5e43de778b57693cd46859eb"),
            "sellerId" : ObjectId("5e43e5cdc11f750864f46820"),
            "amount" : 30,
         }
      {
            "paymentReceivedOnDate" : ISODate("2020-02-12T18:30:00Z"),
             "customerId" : ObjectId("5e43de778b57693cd46859eb"),
            "sellerId" : ObjectId("5e43e5cdc11f750864f46820"),
            "amount" : 160,
         }
     {
            "paymentReceivedOnDate" : ISODate("2020-02-11T18:30:00Z"),
             "customerId" : ObjectId("5e43de778b57693cd46859eb"),
            "sellerId" : ObjectId("5e43e5cdc11f750864f46820"),
            "amount" : 50,
        }

我的问题陈述:

1:首先,我需要计算样本 1 集合的总费用。 针对 [date,customerId,sellerId]

2:其次我需要从样本 2 集合中计算 totalAmount。

3:比我需要计算未付款项,即 [totalCharges - totalAmount]。

4:最后也是最重要的是,我需要将投影结果保存到一个新的集合中,假设“结果”具有以下字段 - ['customerId','sellerId','date','totalCharges','outstanding'(即:[ totalCharges - totalAmount]),'totalAmount'。

您可以尝试以下查询:

db.sample1.aggregate([
    /** groups data & sum up charges */
    { $group: { _id: { date: '$_id.date', customerId: '$_id.customerId', sellerId: '$_id.sellerId' }, totalCharges: { $sum: '$charges' } } },
    /** finds matching docs from sample2 */
    {
        $lookup:
        {
            from: "sample2",
            let: { customerId: '$_id.customerId', sellerId: '$_id.sellerId' },
            pipeline: [
                {
                    $match:
                    {
                        $expr:
                        {
                            $and:
                                [
                                    { $eq: ["$customerId", "$$customerId"] },
                                    { $eq: ["$sellerId", "$$sellerId"] }
                                ]
                        }
                    }
                },
                { $project: { amount: 1, _id: 0 } }
            ],
            as: "TotalAmount" // TotalAmount is an array of objects, each object will have just amount field in it.
        }
    },
    /** retains only needed fields  */
    {
        $project: {
            totalCharges: 1, outstanding: {
                $subtract: ['$totalCharges', {
                    $reduce: {
                        input: '$TotalAmount',
                        initialValue: 0,
                        in: { $add: ["$$value", "$$this.amount"] }
                    }
                }]
            }, TotalAmount: {
                $reduce: {
                    input: '$TotalAmount',
                    initialValue: 0,
                    in: { $add: ["$$value", "$$this.amount"] }
                }
            }
        }
    }
])

测试: MongoDB-Playground

参考: 聚合管道

注意:在聚合结束时,您可以使用$merge$out阶段将聚合结果写入新集合,如果您的 MongoDB v >= 4.2则更喜欢$merge因为它会将字段合并到现有文档/将新文档添加到现有集合或者如果没有找到具有给定名称的集合,它将创建新集合,但是如果提供的集合名称已存在或创建具有提供名称的新集合,则$out将完全替换现有集合。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM