【问题标题】:How to group MongoDB data by property?如何按属性对 MongoDB 数据进行分组?
【发布时间】:2020-06-24 05:44:25
【问题描述】:

类似的问题被问过多次,但我找不到像我这样的问题的答案。

我的数据如下所示:

{ _id: 1, status: 'unpaid', subtotal: 5000, total: 4750, fees: 250 },
{ _id: 2, status: 'received', subtotal: 5000, total: 4750, fees: 250 },
{ _id: 3, status: 'paidout', subtotal: 5000, total: 4750, fees: 250 },
{ _id: <id>, status: 'paidout', subtotal: 5000, total: 4750, fees: 250 },
{ _id: <id>, status: 'unpaid', subtotal: 5000, total: 4750, fees: 250 }

我想要实现的是,我想为所有按状态分组的记录获得total 的总和,如果状态为paidout,那么总和将为subtotal,也是最新记录状态为paidout

这是我现在的代码:

const totals = await Payment.aggregate([
{
    $match: {
        _user: req.user._id,
    }
},
{
    $group: {
        _id: '$status',
        total: {
            $sum: '$subtotal',
        },
        paidout: {
            $sum: '$total'
        },
        lastPayout: {
            $first: '$total'
        }
    }
}
])

这是返回的结果:

[{ _id: 'paidout', total: 102000, paidout: 97962, lastPayout: 52825 },
{ _id: 'received', total: 60000, paidout: 57630, lastPayout: 57630 }]

不是我正在寻找的格式,因此非常感谢任何帮助!

【问题讨论】:

  • 你想要status: 'paidout' 也分组status 字段并求和subtotaltotal 的最新记录吗? latest record 是什么意思? status 字段是否会不时更新?那你怎么说一个文件是最新的?有时间戳吗?

标签: mongodb mongoose mongodb-query aggregation-framework


【解决方案1】:

查询:

db.collection.aggregate([
    /** Checks a conditions and sum-up on either `subtotal` or `total` field */
    /** Checks a conditions and adds last doc in iteration if `status is not paidout` then `latestDoc will be null` */
    {
      $group: {
        _id: "$status",
        totalAmount: { $sum: { $cond: [ { $eq: [ "$status", "paidout" ] }, "$subtotal", "$total" ] } },
        latestDoc: { $last: { $cond: [ { $eq: [ "$status", "paidout" ] }, "$$ROOT", "$$REMOVE" ] } }
      }
    },
    /** stage to remove `latestDoc` field where if it's `null` */
    { $addFields: { latestDoc: { $ifNull: [ "$latestDoc", "$$REMOVE" ] } } }
  ])

测试: mongoplayground

注意:

获取最新文档latestDoc 正在根据插入的订单文档进行。但是,如果您的字段status 已针对现有文档进行了更新,那么如果您想获取最新文档,其中status : 'paidout' 维护一个timestamp 字段,您需要在$group 之前对其进行排序,然后将最后一个文档推送到latestDoc字段。

【讨论】:

猜你喜欢
  • 2021-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-03-17
  • 2015-12-31
  • 1970-01-01
  • 1970-01-01
  • 2018-07-15
相关资源
最近更新 更多