MongoDB 按多个不同字段分组

MongoDB Group by Multiple and DIFFERENT Fields

我知道这个问题已经被问过很多次了,但我似乎找不到我要找的东西。我正在使用 $project 获取 MongoDB 中具有 3 个字段(月、周、值)的文档集合,因此我可以通过将每个月或每周独立分组而不是组合来对它们进行分组以求和值。

我正在使用这个 $project:

let query = await spds.aggregate([
        { $match : { accountID: decoded.accountID, status: 'won', archivedDate: {$gt: new Date(oneYearAgoDate)}} },
        {
            $project: {
                value: 1,
                monthAndYear: { $dateToString: { format: "%m-%Y", date: "$archivedDate" } },
                weekAndYear: { $cond: [ { $gt: ["$archivedDate", new Date(sixMonthsAgoDate) ] }, { $dateToString: { format: "%V-%Y", date: "$archivedDate" } }, null ] },
            }
        },
    ]).toArray();

投影后我得到:

[
{
    "_id": "61b77f2ac0508737c8fe87e9",
    "value": 4900,
    "monthAndYear": "01-2022",
    "weekAndYear": "02-2022",
},
{
    "_id": "61c565584d698f6d61a69e17",
    "value": 11200,
    "monthAndYear": "12-2021",
    "weekAndYear": "51-2021",
},
{
    "_id": "61ea09aaa1040695259635a8",
    "value": 7800,
    "monthAndYear": "12-2021",
    "weekAndYear": "51-2021",
},
{
    "_id": "61ea09cca1040695259635a9",
    "value": 7800,
    "monthAndYear": "10-2021",
    "weekAndYear": "41-2021",
},
{
    "_id": "61ea0a21a1040695259635ab",
    "value": 1600,
    "monthAndYear": "12-2021",
    "weekAndYear": "52-2021",
},
{
    "_id": "61ea0b2594c47ca489c5573b",
    "value": 7000,
    "monthAndYear": "02-2022",
    "weekAndYear": "06-2022",
},
{
    "_id": "62031c7186a5daed72c7bd3c",
    "value": 0,
    "monthAndYear": "02-2022",
    "weekAndYear": "06-2022",
},
{
    "_id": "62031c7e86a5daed72c7bd3d",
    "value": 0,
    "monthAndYear": "02-2022",
    "weekAndYear": "06-2022",
},
{
    "_id": "62153dbb94fbec0a703a84e9",
    "value": 6920,
    "monthAndYear": "12-2021",
    "weekAndYear": "50-2021",
}

]

使用这个 $group 后:

let query = await spds.aggregate([
        { $match : { accountID: decoded.accountID, status: 'won', archivedDate: {$gt: new Date(oneYearAgoDate)}} },
        {
            $project: {
                value: 1,
                monthAndYear: { $dateToString: { format: "%m-%Y", date: "$archivedDate" } },
                weekAndYear: { $cond: [ { $gt: ["$archivedDate", new Date(sixMonthsAgoDate) ] }, { $dateToString: { format: "%V-%Y", date: "$archivedDate" } }, null ] },
            }
        },
        {
            $group: {
                _id: {
                    "monthAndYear": "$monthAndYear",
                    "weekAndYear": "$weekAndYear",
                  },
               value: { $sum: "$value" },
            }
        },
    ]).toArray();

我得到:

[
{
    "_id": {
        "monthAndYear": "02-2022",
        "weekAndYear": "06-2022"
    },
    "value": 7000
},
{
    "_id": {
        "monthAndYear": "12-2021",
        "weekAndYear": "52-2021"
    },
    "value": 1600
},
{
    "_id": {
        "monthAndYear": "12-2021",
        "weekAndYear": "50-2021"
    },
    "value": 6920
},
{
    "_id": {
        "monthAndYear": "01-2022",
        "weekAndYear": "02-2022"
    },
    "value": 4900
},
{
    "_id": {
        "monthAndYear": "10-2021",
        "weekAndYear": "41-2021"
    },
    "value": 7800
},
{
    "_id": {
        "monthAndYear": "12-2021",
        "weekAndYear": "51-2021"
    },
    "value": 19000
}

]

但我需要得到:

月份和年份:

[
{
    "_id": {
        "monthAndYear": "02-2022"
    },
    "value": 7000
},
{
    "_id": {
        "monthAndYear": "12-2021"
    },
    "value": 27520
},
{
    "_id": {
        "monthAndYear": "01-2022"
    },
    "value": 4900
},
{
    "_id": {
        "monthAndYear": "10-2021"
    },
    "value": 7800
}

]

周和年:

[
{
    "_id": {
        "weekAndYear": "52-2021"
    },
    "value": 1600
},
{
    "_id": {
        "weekAndYear": "02-2022"
    },
    "value": 4900
},
{
    "_id": {
        "weekAndYear": "51-2021"
    },
    "value": 19000
},
{
    "_id": {
        "weekAndYear": "06-2022"
    },
    "value": 7000
},
{
    "_id": {
        "weekAndYear": "50-2021"
    },
    "value": 6920
},
{
    "_id": {
        "weekAndYear": "41-2021"
    },
    "value": 7800
}

] 我当时只需要按一个字段分组,而不是同时按两个字段分组。任何帮助将不胜感激。

魔术运算符是$facet

我更喜欢 $dateTrunc 和根据 ISO-8601

的日期格式,而不是按格式分组
db.getCollection("collection").aggregate([
   {
      $facet: {
         monthAndYear: [
            {
               $group: {
                  _id: { $dateTrunc: { date: "$archivedDate", unit: "month", timezone: "Europe/Zurich" } },
                  value: { $sum: "$value" }
               }
            },
            { $set: { _id: [{ k: "monthAndYear", v: { $dateToString: { format: "%Y-%m", date: "$_id" } } }] } },
            { $set: { _id: { $arrayToObject: "$_id" } } }
         ],
         weekAndYear: [
            {
               $group: {
                  _id: { $dateTrunc: { date: "$archivedDate", unit: "week", timezone: "Europe/Zurich", startOfWeek: "monday" } },
                  value: { $sum: "$value" }
               }
            },
            { $set: { _id: [{ k: "weekAndYear", v: { $dateToString: { format: "%G-W%V", date: "$_id" } } }] } },
            { $set: { _id: { $arrayToObject: "$_id" } } }
         ],
      }
   },
   { $project: { data: { $concatArrays: ["$monthAndYear", "$weekAndYear"] } } },
   { $unwind: "$data" },
   { $replaceWith: "$data" }
])