mongodb - 查找按今天、本周、本月分组的文档数
问题描述
我正在使用 Redash 执行数据可视化,并且我的文档具有如下结构:
{
"id" : "12345",
"created_at" : "07/06/19 08:53"
},
{
"id" : "123456",
"created_at" : "07/06/19 12:13"
},
{
"id" : "123457",
"created_at" : "06/06/19 20:18"
}
我想要的结果是
{
"TimeRange" : "today",
"count" : "6"
},
{
"TimeRange" : "this Week",
"count" : 15
},
{
"TimeRange" : "this Month",
"count" : 40
}
我可以使用按日期分组
db.doc.aggregate([
{ $group:
{ _id: { $dateToString: { format: "%Y-%m-%d", date: "$created_at" } }, count: { $sum: 1 } } }
])
但是有什么方法最好使用聚合在指定的不同时间范围内显示结果?
解决方案
这里的日期格式特别令人讨厌,因为缺少世纪和月份与日期的歧义。存储真正的日期时间会更好,这样日期操作就可以轻松应对它们。但是对于这个练习,让我们假设你不能。MongoDB 中的日期函数避免了假设,因此没有无世纪dateFromString
格式组件,因此我们必须自己完成。好的。让我们从这组数据开始,类似于你的:
var r = [
// Assume MM/DD/YY where YY is 20YY
// last week
{"created_at" : "06/01/19 10:53"},
// yesterday, this week
{"created_at" : "06/05/19 10:53"},
// today
{"created_at" : "06/06/19 08:53"},
{"created_at" : "06/06/19 12:53"},
{"created_at" : "06/06/19 18:33"},
// tomorrow, this week
{"created_at" : "06/07/19 19:33"},
{"created_at" : "06/07/19 20:33"},
// later, but this month
{"created_at" : "06/27/19 07:33"},
{"created_at" : "06/27/19 08:33"},
// next month
{"created_at" : "07/04/19 11:33"},
// next year
{"created_at" : "07/04/20 11:33"}
];
为了弄清楚今天、本月等,我们需要在我们存储的数据之外设置一个目标日期。
today = new ISODate("2019-06-06");
target_week = 22; // up to you to implement
target_mon = today.getMonth() + 1; // MongoDB mon is 1-12, not 0-11
target_year = today.getFullYear();
这是一个解决方案。我们可以使用快捷方式并只使用日期字符串的片段,但我们将构建一个真实的日期,它可以很好地设置我们执行特定请求分组之外的其他事情。这意味着我们将在我们将它们放入日期之后将它们拉出日期。
db.foo.aggregate([
// Create a real date from the pieces. Ignore time bits for now:
{ $addFields: {"rd":
{$dateFromParts : {
"year": {$add: [2000,{$toInt: {$substr: ["$created_at",6,2]}} ] },
"month": {$toInt: {$substr: ["$created_at",0,2]}},
"day": {$toInt: {$substr: ["$created_at",3,2]}}
}}
}}
// Now use facet to act as a "multigroup":
,{$facet: {
"today": [
{$match: { "rd": today}}, {$count: "n"}
]
,"This week": [
{$project: { "w": {$week: "$rd"}, "y": {$year: "$rd"} }}
,{$match: { "w": target_week, "y": target_year}}
,{$count: "n"}
]
,"This month": [
{$project: { "m": {$month: "$rd"}, "y": {$year: "$rd"} }}
,{$match: { "m": target_mon, "y": target_year}}
,{$count: "n"}
]
}}
,"This year": [
{$project: { "y": {$year: "$rd"} }}
,{$match: { "y": target_year}}
,{$count: "n"}
]
}}
]);
产生
{
"today" : [
{
"n" : 3
}
],
"This week" : [
{
"n" : 6
}
],
"This month" : [
{
"n" : 9
}
],
"This year" : [
{
"n" : 10
}
]
}
推荐阅读
- java - 为什么我的 RecyclerView 不显示任何内容?
- discord.js - 每当我输入“$effect [pokemon type]”时,Discord 机器人都没有反应
- lotus-notes - 更改传入外部电子邮件的徽标
- html - 设置颜色输入的高度
- react-native - 将功能组件转换为类组件 React
- javascript - 通过 Google Apps 脚本发送电子邮件时出现问题
- git - 如何在远程 git repo 中获取单个文件的 sha
- macos - 试图回到 ZSH 脚本中的“检查点”
- xero-api - 如何使用 xere-node 从 Xero API 获取银行交易记录
- flutter - 可重复使用的 TextStyle 或 BoxDecoration,其中包含 Future 函数 - SharedPrefs - How To?