node.js - 如何使用日期字段按周、小时和天过滤文档
问题描述
我是 express 和 mongoDB 的初学者。我正在从事一项任务,其中我有一个称为销售类型的模型-
{
userName : String,
amount : Number,
date : Date
}
现在我必须创建一个 API,它应该有 3 种类型的参数——“每日”、“每周”、“每月”。如果参数是
每天 - 然后我必须从销售表中根据一天中的每个小时发送统计信息(金额总和)。
每周 - 然后我必须根据一周中的每一天发送统计数据
每月 - 然后我必须根据每月的每一天发送统计信息
在思考了一些逻辑之后,我想出了这个-
我能够进行每日统计,但它看起来也很复杂
app.get("/fetchSales/:id",async (req, res)=>{
const { id } = req.params;
const allSales = await sales.find({});
const dates = [];
for(i in allSales){
let date = allSales[i].date.toISOString().replace('Z', '').replace('T', '');
const dateFormat = dayjs(date);
dateFormat.amount = allSales[i].amount;
dates.push(dateFormat);
}
if(id === "daily") {
const stats = {};
for(let hour = 0; hour < 24; hour++) {
let sum = 0
for (x in dates) {
if (dates[x]["$H"] === hour) sum += dates[x].amount
}
stats[hour] = sum;
}
res.send(stats);
}
})
但展望未来,我必须使用几个循环,而且看起来不太好。我读过也许聚合查询可以帮助我。
js给我的结构天数是-
d {
'$L': 'en',
'$d': 2021-01-13T13:00:00.000Z,
'$x': {},
'$y': 2021,
'$M': 0,
'$D': 13,
'$W': 3,
'$H': 18,
'$m': 30,
'$s': 0,
'$ms': 0,
amount: 1700 //added on my own//
}
我想要的一些输出结构 - 每天
{
0: 0$,
1: 0$,
2: 24$,
...
23: 2$
}
知道我该如何处理吗?
解决方案
您可以根据输入构建查询条件,但让 Mongodb 完成繁重的工作:
app.get("/fetchSales/:id", async (req, res) => {
const {id} = req.params;
const groupCondition = {
sum: {$sum: 1}
};
if (id === 'monthly') {
groupCondition._id = {$week: '$date'};
} else if (id === 'weekly') {
groupCondition._id = {$dayOfMonth: '$date'};
} else if (id === 'weekly') {
groupCondition._id = {$hour: '$date'};
} else {
// can this happen? what to do here.
}
const allSales = await sales.aggregate([
{
$group: groupCondition
},
{
$sort: {
_id: 1
}
}
]);
});
请注意,这不会返回文档计数为 0 的天/周/小时,您必须通过管道或代码手动插入它们。
$group
对于每个完整日期而不是某个一般小时/天的实际ing,您应该使用以下命令:
app.get("/fetchSales/:id", async (req, res) => {
const {id} = req.params;
const groupCondition = {
_id: {year: {$year: '$date'}, $month: {'$month': "$date"}, week: {'$week': "$date"} },
sum: {$sum: 1},
date: {$first: '$date'} //for sorting
};
switch (id) {
case 'weekly':
groupCondition._id.$dayOfMonth = {$dayOfMonth: '$date'};
case 'daily':
groupCondition._id.$hour = {$hour: '$date'};
}
const allSales = await sales.aggregate([
{
$group: groupCondition
},
{
$sort: {
date: 1
}
},
{
$project: {
_id: 1,
sum: 1
}
}
]);
});
这将为您提供此结构中的文档:
[
{
_id: { year: 2020, month: 5, week: 13, day: 22, hour: 5},
sum: 50
}
]
推荐阅读
- elasticsearch - Elasticsearch - 获得不同的结果,其中至少有 2 个子存储桶的结果
- java - 如何让正则表达式只包含大写字母或数字?
- python - 我的循环如何只给我第二个索引。并且没有得到第三个索引元素
- javascript - 删除里面的项目时,ScrollView高度不更新
- javascript - 如何将条件匹配技术编码到我的程序中?
- reactjs - 在另一个屏幕中反应上下文
- r - 如何在 R 中创建 Circlize Circos 图或弦图?
- botframework - 如何获取 Action.Submit 类型:登录以触发 Teams Bot Card 中的弹出窗口
- java - 升级到大苏尔 1.6。现在 maven 显示此错误:无法找到或加载主类 org.codehaus.plexus.classworlds.launcher.Launcher
- javascript - 创建带有菜单栏的滑块 - 作为链接的标题未正确对齐