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" }
])
我知道这个问题已经被问过很多次了,但我似乎找不到我要找的东西。我正在使用 $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" }
])