【问题标题】:MongoDB get SUM of fields with conditionsMongoDB获取具有条件的字段的总和
【发布时间】:2021-11-04 23:11:19
【问题描述】:

在我的后端,我使用带有 nodejs 和 mongoose 的 mongoDB

我在 mongodb 中有很多具有这种结构的记录:

{
  ..fields
  type: 'out',
  user: 'id1', <--mongodb objectID,
  orderPayment: [
    {
      _id: 'id1',
      paid: true,
      paymentSum: 40
    },
    {
      _id: 'id2',
      paid: true,
      paymentSum: 60,
    },
    {
      _id: 'id3',
      paid: false,
      paymentSum: 50,
    }
  ]
},
{
..fields
type: 'in',
user: 'id1', <--mongodb objectID
orderPayment: [
  {
    _id: 'id1',
    paid: true,
    paymentSum: 10
  },
  {
    _id: 'id2',
    paid: true,
    paymentSum: 10,
  },
  {
    _id: 'id3',
    paid: false,
    paymentSum: 77,
  }
]
}

我需要按“类型”对这些记录进行分组,并根据条件得到总和。 需要获取“付费”记录的总和和无付费记录的总和。

为了更好地理解,这是我需要得到的结果

输出是:

{
  out { <-- type field
    paid: 100, <-- sum of paid
    noPaid: 50 <-- sum of noPaid
  },
  in: { <-- type field
    paid: 20, <-- sum of paid
    noPaid: 77 <-- sum of noPaid
  }
}

【问题讨论】:

    标签: node.js mongodb mongoose


    【解决方案1】:

    不同的解决方案是这个。它可能比@YuTing 的解决方案提供更好的性能:

    db.collection.aggregate([
      {
        $project: {
          type: 1,
          paid: {
            $filter: {
              input: "$orderPayment",
              cond: "$$this.paid"
            }
          },
          noPaid: {
            $filter: {
              input: "$orderPayment",
              cond: { $not: "$$this.paid" }
            }
          }
        }
      },
      {
        $set: {
          paid: { $sum: "$paid.paymentSum" },
          noPaid: { $sum: "$noPaid.paymentSum" }
        }
      },
      {
        $group: {
          _id: "$type",
          paid: { $sum: "$paid" },
          noPaid: { $sum: "$noPaid" }
        }
      }
    ])
    

    Mongo Playground

    【讨论】:

    • 非常感谢!如何按类型获取记录数?例如输出:2 输入:5
    【解决方案2】:

    $group中使用$cond

    db.collection.aggregate([
      {
        "$unwind": "$orderPayment"
      },
      {
        "$group": {
          "_id": "$type",
          "paid": {
            "$sum": {
              $cond: {
                if: { $eq: [ "$orderPayment.paid", true ] },
                then: "$orderPayment.paymentSum",
                else: 0
              }
            }
          },
          "noPaid": {
            "$sum": {
              $cond: {
                if: { $eq: [ "$orderPayment.paid", false ] },
                then: "$orderPayment.paymentSum",
                else: 0
              }
            }
          }
        }
      }
    ])
    

    mongoplayground

    【讨论】:

    • 你不需要if: { $eq: [ "$orderPayment.paid", true ] },直接写if: "$orderPayment.paid"
    猜你喜欢
    • 2023-03-23
    • 2023-01-13
    • 2015-10-16
    • 1970-01-01
    • 2020-05-09
    • 1970-01-01
    • 2022-11-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多