使用MongoDB/Mongoose.js按月对标签进行分组



mongodb中的集合如下所示:

文章:

// ...
tags: [
{
id: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Tag',
required: true,
}
// ... 
}
],
date: {
type: Date,
}
// ...

我想写一个查询,结果如下:

[
{
"month": "Jan",
"tag1": 5,
"tag2": 80,
// ...
}, 
{
"month": "Feb",
"tag1": 30,
"tag2": 95,
// ...
},
// ...
]

我想我需要使用聚合。对吗?

我写了这个,但结果不是我想要的。

const monthStrings = ["", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
Posst.aggregate([
{
$match: {
$expr: {
$and: [
{ $gt: ["$created_at", oneYearFromNow] },
{ $lt: ["$created_at", dateNow] }
],
}
}
},
{
$group: {
_id: {
month: { $month: "$date" },
year: { $year: "$date" },
},
count: {
$sum: 1
}
}
},
{
$project: {
_id: {
$concat: [
{
$arrayElemAt: [
monthStrings,
"$_id.month"
]
},
"-",
"$_id.year"
]
},
count: 1,
}
}
])

我怎样才能得到我想要的结果?

(返回的格式其实并不重要,但我试图实现的是在一个查询中检索同一分组的多个计数(每月一个(。(

为了对每个标记的文档进行计数,您需要按标记标识符进行分组。由于标记在数组中,最简单的方法是在分组之前先展开数组。最后,为了在单个文档中获取同一个月的所有标签,您需要执行第二次分组操作。例如(假设您要使用的标签的名称在"ref"字段中(:

Posst.aggregate([
{
$match: ... 
},
{
// Unwind the tags array, produces one document for each element in the array
$unwind: '$tags'
},
{
// Group by month, year and tag reference
$group: {
_id: {
month: { $month: '$date' },
year: { $year: '$date' },
tag: '$tag.ref'
},
count: { $sum: 1 }
}
},
{
// Group again by month and year to aggregate all tags in one document
$group: {
_id: {
month: '$_id.month',
year: '$_id.year'
},
// Collect tag counts into an array
tagCounts: {
$push: {
k: '$_id.tag',
v: '$count'
}
}
}
},
{
// Reshape document to have each tag in a separate field
$replaceRoot: {
newRoot: {
$mergeObjects: [ 
{ month: '$_id.month', year: '$_id.year' },
{ $arrayToObject: '$tagCounts' }
]
}
}
}
])

最新更新