【问题标题】:Mongodb : Query based on time in ISODate formatMongodb:基于 ISODate 格式的时间查询
【发布时间】:2016-02-09 18:55:14
【问题描述】:

假设MongoDB数据库中的示例文档如下:

 { "date" : ISODate("2015-11-09T05:58:19.474Z") }
 { "date" : ISODate("2014-10-25T07:30:00.241Z") }
 { "date" : ISODate("2015-11-30T15:24:00.251Z") }
 { "date" : ISODate("2012-01-10T18:36:00.101Z") }

预期:

 { "date" : ISODate("2015-11-09T05:58:19.474Z") }
 { "date" : ISODate("2014-10-25T07:30:00.241Z") }

我有兴趣查找“日期”字段中的时间在 04:00 和 08:00 之间的文档,无论日、月和年。间接查询必须匹配日期字段中的任何“YYYY-MM-DDT”。

我的方法是,从节点查询假定日期持续时间内的所有文档,然后对于与查询匹配的每个文档,将文档的“日期”字段与“yyyy-MM-DDT”+“required_time”( “YYYY-MM-DD 是从每个文档的“日期字段”中复制的,通过使用 moment.js 模块转换为 moment() 并获取月、日和年进行比较。

有什么方法可以查询直接得到同样的结果吗?

注意:我是用nodejs连接mongodb

【问题讨论】:

  • 如何创建一个时间字段,在其中以 0800 表示 8:00 的格式存储时间,并使用 {$gt:0400, $lt:0800} 查询数据库。我想这将是获得结果的最快方法。

标签: mysql node.js mongodb date momentjs


【解决方案1】:

一种方法是使用aggregation framework,特别是$redact 运算符,它根据文档及其子文档中的值剥离文档内容流。根据布尔表达式的结果,可以从流中修剪文档,在检查其子文档后将其包含在流中,或者只是将其完整传递到流中。 $redact 背后的想法是让从流中删除敏感信息变得容易。

在您的情况下,条件表达式使用 $cond 运算符和 $and 布尔运算符来表示具有比较运算符的时间范围之间的逻辑与$gt$lt。使用 $hour 日期运算符将 date 字段的小时作为 0 到 23 之间的数字返回。因此您的最终聚合如下所示:

db.collection.aggregate([
    {
        "$redact": {
            "$cond": {
                "if": { 
                    "$and": [
                        { "$gt": [ {"$hour": "$date"}, 4] },
                        { "$lt": [ {"$hour": "$date"}, 8] }
                    ]                 
                },
                "then": "$$KEEP",
                "else": "$$PRUNE"
            }
        }        
    }
])

样本输出:

/* 0 */
{
    "result" : [ 
        {
            "_id" : ObjectId("56404450472fe25cc6b85886"),
            "date" : ISODate("2015-11-09T05:58:19.474Z")
        }, 
        {
            "_id" : ObjectId("56404450472fe25cc6b85887"),
            "date" : ISODate("2014-10-25T07:30:00.241Z")
        }
    ],
    "ok" : 1
}

【讨论】:

  • 你能解释一下查询中的这部分 "$gt": [ {"$hour": "$date"}, 4]" 吗?
  • 由于您有兴趣查找 "date" 字段中的时间在 04:00 到 08:00 之间的文档,无论日月年,表达式 "$gt": [ {"$hour": "$date"}, 4]" 将查询其中的文档date 字段的小时部分大于 4。这相当于说 getHour(date) > 4
  • 谢谢。假设如果还需要考虑分钟,比如 04:00 到 07:45 之间的文档,那么我们如何修改查询?
  • 看起来Mongodb : Query based on time in ISODate format 解决了不是吗?至于“下一个”问题,那就是different question,考虑单独发一下。
  • @helloworld 谢谢。一般情况下,$hour 运算符仅应用于聚合管道,而不是 find() 查询。因此,在您的聚合中,您的管道有两个步骤,$project 创建一个包含小时部分的新字段,下一个阶段$match 然后查询文档。
猜你喜欢
  • 2016-02-13
  • 1970-01-01
  • 2018-02-22
  • 2020-11-28
  • 2017-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多