mongodb агрегировать по месяцам + дате и сортировать - PullRequest
1 голос
/ 28 марта 2020

Я создал эту агрегатную операцию, чтобы возвращать список заказов на каждый месяц. То есть, что-то вроде этого:

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 Ответ

2 голосов
/ 28 марта 2020

В вашем $group в вашем _id может быть несколько подэлементов. Это может позволить вам иметь год и месяц как две отдельные сущности, которые вы можете затем представить любым удобным вам способом. Ваша группа и сортировка будут иметь вид:

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

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

В приведенном выше примере я предположил, что вы хотите отсортировать по году как первичному и месяцу как вторичному и в порядке возрастания, например, вы получите январь 2019 г., февраль 2019 г., ..., январь 2020 г., февраль 2020 г., март 2020 г.

Если вы хотите иметь отформатированную версию года и месяца, вы, конечно, можете добавить ее в $addFields или как часть $group. Например:

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

Альтернатива

Используйте $dateToString для форматирования даты в $group в _id (https://docs.mongodb.com/manual/reference/operator/aggregation/dateToString/). Следующее должно сделать трюк:

{ $dateToString: {
    date: "$launchDate",
    format: ""%Y%m"
} }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...