node.js - 使用 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' }
]
}
}
}
])
推荐阅读
- r - 如何创建相关矩阵并能够对双精度列进行子集化?
- r - UseMethod(“select”)中的错误:没有适用于“select”的方法应用于类“c('double','numeric')”的对象
- java - Java 应用程序 - 用于在 Mac 上激活按钮的 Space vs Enter
- pyspark - 如何从现有时间戳列将新的日期时间列添加到火花数据帧
- mysql - 使用内置函数 MySQL 设置的变量查询表
- c# - 使用 C# Winforms 自动化 mRemoteNG
- java - @Max 和 @Min 不适用于方法参数
- javascript - 特定浏览器选项卡上的额外 HTML 内容
- laravel - Laravel Sanctum:访问已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查
- unity3d - Hololens 2 MRTK Unity 应用程序:场景锁定到相机/头部