这是可能的,因为输出的长度始终是固定的。所以想法是生成一个长度为 12 的数组,然后填充那些有数据的月份,否则为空计数。所以试试这个:
解决方案 #1
db.calendar.aggregate([
// Put your match stage here.
{
$group: {
_id: { $month: "$dos" },
count: { $sum: 1 }
},
},
{
$group: {
_id: null,
array: { $push: "$$ROOT" }
}
},
{
$addFields: {
array: {
$map: {
input: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
as: "month",
in: {
$cond: {
if: { $in: ["$$month", "$array._id"] },
then: {
$arrayElemAt: [
"$array",
{ $indexOfArray: ["$array._id", "$$month"] }
]
},
else: {
_id: "$$month",
count: 0
}
}
}
}
}
}
},
{ $unwind: "$array" },
{
$sort: { "array._id": 1 }
},
{
$project: {
_id: 0,
count: "$array.count",
month: "$array._id"
}
}
]);
解决方案 #2:与第一个相比效率更高。
db.calendar.aggregate([
// Put your match stage here.
{
$group: {
_id: { $month: "$dos" },
count: { $sum: 1 }
},
},
{
$group: {
_id: null,
array: { $push: "$$ROOT" }
}
},
{
$addFields: {
array: {
$map: {
input: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
as: "month",
in: {
$let: {
vars: {
index: { $indexOfArray: ["$array._id", "$$month"] }
},
in: {
$cond: [
{ $gt: ["$$index", -1] },
{ $arrayElemAt: ["$array", "$$index"] },
{ _id: "$$month", count: 0 }
]
}
}
}
}
}
}
},
{ $unwind: "$array" },
{
$sort: { "array._id": 1 }
},
{
$project: {
_id: 0,
count: "$array.count",
month: "$array._id"
}
}
]);
输出:
/* 1 */
{
"count" : 2,
"month" : 1
},
/* 2 */
{
"count" : 2,
"month" : 2
},
/* 3 */
{
"count" : 1,
"month" : 3
},
/* 4 */
{
"count" : 0,
"month" : 4
},
/* 5 */
{
"count" : 0,
"month" : 5
},
/* 6 */
{
"count" : 0,
"month" : 6
},
/* 7 */
{
"count" : 0,
"month" : 7
},
/* 8 */
{
"count" : 1,
"month" : 8
},
/* 9 */
{
"count" : 0,
"month" : 9
},
/* 10 */
{
"count" : 1,
"month" : 10
},
/* 11 */
{
"count" : 0,
"month" : 11
},
/* 12 */
{
"count" : 0,
"month" : 12
}
测试数据:
/* 1 createdAt:3/17/2021, 7:27:28 PM*/
{
"_id" : ObjectId("60520ac8479cd440a079c271"),
"dos" : ISODate("2021-01-15T00:00:00.000+05:30")
},
/* 2 createdAt:3/17/2021, 7:27:28 PM*/
{
"_id" : ObjectId("60520ac8479cd440a079c272"),
"dos" : ISODate("2021-03-03T00:00:00.000+05:30")
},
/* 3 createdAt:3/17/2021, 7:27:28 PM*/
{
"_id" : ObjectId("60520ac8479cd440a079c273"),
"dos" : ISODate("2021-02-14T00:00:00.000+05:30")
},
/* 4 createdAt:3/17/2021, 7:27:28 PM*/
{
"_id" : ObjectId("60520ac8479cd440a079c274"),
"dos" : ISODate("2021-01-26T00:00:00.000+05:30")
},
/* 5 createdAt:3/17/2021, 7:27:28 PM*/
{
"_id" : ObjectId("60520ac8479cd440a079c275"),
"dos" : ISODate("2021-02-28T00:00:00.000+05:30")
},
/* 6 createdAt:3/17/2021, 7:27:28 PM*/
{
"_id" : ObjectId("60520ac8479cd440a079c276"),
"dos" : ISODate("2021-08-15T00:00:00.000+05:30")
},
/* 7 createdAt:3/17/2021, 7:27:28 PM*/
{
"_id" : ObjectId("60520ac8479cd440a079c277"),
"dos" : ISODate("2021-10-02T00:00:00.000+05:30")
}