建立汇总结果的总和

时间:2020-07-06 00:55:43

标签: javascript mongodb typescript mongoose aggregation-framework

是否可以将字段添加到汇总结果中?我的目标是对所有结果求和。目前,我只是减少结果,但是我认为这不如通过查询来解决。

aggregate([
      {
        $match: {
          time: { $gte: start, $lte: end },
        },
      },
      {
        $group:
          {
            _id: { $dateToString: { format: '%Y-%m-%d', date: '$time' } },
            totalAmount: { $sum: '$payment.amount' },
          },
      },
    ]).exec().then((result) => {
      return {
        total: result.reduce(((acc, curr) => acc + curr.totalAmount), 0),
        dates: result,
      };
    });

结果是:

{
   "_id":"2020-06-06",
   "totalAmount":12
},
{
   "_id":"2020-07-06",
   "totalAmount":12
}

有什么主意,我想如何获得所有的总金额,看起来像这样但没有减少的部分?

{
    "total": 24,
    "dates": [
        {
            "_id": "2020-06-06",
            "totalAmount": 12,      
        },
        {
            "_id": "2020-07-06",
            "totalAmount": 12,    
        }
    ]
}

1 个答案:

答案 0 :(得分:1)

您可以同时使用两个查询

const [result, totalAmount] = await Promise.all([
  Model.aggregate([
    { $match: { time: { $gte: start, $lte: end } } },
    {
      $group: {
        _id: { $dateToString: { format: "%Y-%m-%d", date: "$time" } },
        totalAmount: { $sum: "$payment.amount" },
      }
    },
  ]),
  Model.aggregate([
    { $match: { time: { $gte: start, $lte: end } } },
    {
      $group: {
        _id: null,
        totalAmount: { $sum: "$payment.amount" },
      }
    },
  ])
])

return {
  total: result,
  dates: totalAmount,
}

或者可以使用$facet

const result = await Model.aggregate([
  { $match: { time: { $gte: start, $lte: end } } },
  {
    $facet: {
      result: [
        {
          $group: {
            _id: {
              $dateToString: { format: "%Y-%m-%d", date: "$time" },
            },
            totalAmount: { $sum: "$payment.amount" },
          },
        },
      ],
      totalAmount: [
        {
          $group: {
            _id: null,
            totalAmount: { $sum: "$payment.amount" },
          },
        },
      ],
    },
  },
]);


return {
  total: _.get(result, "[0].result", []),
  dates: _.get(result, "[0].totalAmount.totalAmount", 0),
}