mongodb按月+日期聚合并排序

时间:2020-03-28 00:43:27

标签: node.js mongodb mongoose

我创建了此汇总操作,以返回每个月的订单列表。就是这样:

month1: [orders],
month2: [orders],
...

但是,我希望将其从最近到最近的一个月排序。您可以看到我的组是并接月份+年份,但有一个问题。如果我只是简单地执行月+年,那么对事物进行排序将不起作用:

MYYYY
12020
22020
...
92020
102020

如您所见,当我们到达第10个月时,订单被打破。收获是每个月都要添加10,所以我们最终得到

MYYYY
112020
122020
...
192020
202020
212020
222020
102021

可进行订购的商品,但在第二年2021年终止。

那么,如何以一种可以排序但又可以在响应中漂亮地显示事物的方式按月和年排序?容易解析的东西。

        r = await Order.aggregate([
            {
                $match: {
                    launchDate: { "$gte": new Date(req.query.minDate), "$lte": new Date(req.query.maxDate) },
                    withdrawer: { $regex: utils.diacriticSensitiveRegex(req.query.withdrawer), $options: 'i' },
                    deleted: false
                }
            },
            {
                $sort: {
                    launchDate: 1
                }
            },
            {
                $group: {
                    _id: {
                        $concat: [
                            {
                                $toString: {
                                    $year: "$launchDate"
                                }
                            },
                            {
                                $toString: {
                                    $add: [{ $month: "$launchDate" }, 10]
                                }
                            }
                        ]
                    },
                    withdraws: {
                        $push: "$$ROOT"
                    }

                }
            },
            {
                $sort: {
                    _id: -1
                }
            },
            {
                $addFields: {
                    dateRange: "$_id"
                }
            },
            {
                $skip: skip
            },
            {
                $limit: perPage
            }
        ]);

1 个答案:

答案 0 :(得分:2)

$group中,您可以在_id中包含多个子元素。这可以让您将年和月作为两个独立的实体,然后可以按自己喜欢的任何方式进行展示。您的分组和排序将是:

{
    $group: {
        _id: {
            year: {
                $year: "$launchDate"
            },
            month: {
                $month: "$launchDate"
            }
        },
        withdraws: {
            $push: "$$ROOT"
        }

    }
},
{
    $sort: {
        "_id.year": 1,
        "_id.month": 1
    }
},

在上面的示例中,我假设您要按升序对年份进行排序,例如,按年您将获得2019年1月,2019年2月,...,2020年1月,2020年2月,2020年3月。

如果您希望获得年份和月份的格式化版本,当然可以将其添加到$addFields中或作为$group的一部分。例如:

{
    $addFields: {
        formatted: {
            $concat:[
                {$toString:"$_id.year"},
                {$cond: {if: {$lt: ["$_id.month", 10]}, then: "0", else: ""}},
                {$toString: "$_id.month"}
            ]
        }
    }
}

替代

使用$dateToString$grouphttps://docs.mongodb.com/manual/reference/operator/aggregation/dateToString/)下的_id中设置日期格式。以下应该可以解决问题:

{ $dateToString: {
    date: "$launchDate",
    format: ""%Y%m"
} }