当前位置: 首页 > 知识库问答 >
问题:

如何使用日期字段按周、小时和天筛选文档

董良策
2023-03-14

我是express和MongoDB的初学者。我在做一个任务,我有一个模型叫销售-

{
    userName : String,
    amount   : Number,
    date     : Date
}

现在我必须创建一个API,它应该有一个三种类型的参数-“daily”,“weekly”,“monthly”。如果参数为

每天-然后我必须发送统计(金额的总和)的基础上每一个小时的一天从销售表。

每周-然后我必须发送统计的基础上每一天的一周

每月-然后我必须发送统计数据的基础上,每月的每一天

在思考了一些逻辑之后,我想出了这个-

我能做每天的统计,但看起来也很复杂

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$
}

知道我该怎么处理这件事吗?

共有1个答案

艾原
2023-03-14

您可以根据输入构建查询条件,但让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按完整日期而不是按特定的一般小时/天执行,应使用以下命令:

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
    }
]
 类似资料:
  • 问题内容: 我想根据日期从数据库中筛选值。 数据库中的日期包含以下值:2008-12-28 18:00:00。我的班级有一个DateTime变量,具体取决于我要过滤的变量。理想情况下,它将像这样工作: +根据需要调整myDateTime.Date格式。 但是它抛出一个EvaluateException:“该表达式包含未定义的函数调用DATE()。” 尽管如果直接执行SQL语句,则可以在过滤器中使用

  • 问题内容: 我有一些文件: 如何按地区过滤/选择不同的文档? 在SQL中,我可以使用GROUP BY。我尝试了条件聚合,但返回的计数却不同。 感谢您的帮助!:-) 问题答案: 如果您的ElasticSearch版本为1.3或更高版本,则可以使用top_hits类型的子聚合,默认情况下,它将为您提供按查询分数排序的前三个匹配文档(此处为1,因为您使用match_all查询)。 您可以将参数设置为3以

  • 问题内容: 有人可以向我解释为什么以下过滤器在月份和日期级别不起作用吗?按年份进行过滤似乎有效,但其他两个方法却无效。 快速更新以演示在创建和处理查询集之前我得到了相同的行为: 这里有更多值得深思的地方: 问题答案: Django文档给出了将时区定义安装到数据库的指令: SQLite:安装-转换实际上是在Python中执行的。 PostgreSQL:无要求(请参阅时区)。 Oracle:无要求(请

  • 问题内容: 我正在使用美国/纽约时区。在秋季,我们“退后”一个小时-实际上是在凌晨2点“获得”一个小时。在过渡点发生以下情况: 它是01:59:00 -04:00, 然后一分钟后变成:01 :00 : 00 -05:00 因此,如果您只是简单地说“ 1:30 am”,那么您是指第一次还是1:30滚动还是第二次就不清楚了。我正在尝试将计划数据保存到MySQL数据库,并且无法确定如何正确保存时间。 这

  • 问题内容: 我有一个称为 activity_dt 的日期时间,数据如下所示: 如何按日期和小时分组? 问题答案: SQL Server: 甲骨文: MySQL的:

  • 目前,我已经知道如何从(时间戳)日期字段中筛选日期范围。这是一个简单的问题: 但是,当你对基于时间的范围感兴趣时,如何过滤日期,比如gte:“8:00:00”和lte:“10:00:00”?这有可能吗? 换句话说,我的要求是:如何让所有事件在本月(15-11-01/15-11-30)发生,但只能在上午8:00到10:00之间发生?