Mongodb:基于 ISODate 格式的时间查询

Posted

技术标签:

【中文标题】Mongodb:基于 ISODate 格式的时间查询【英文标题】:Mongodb : Query based on time in ISODate format 【发布时间】: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 查询数据库。我想这将是获得结果的最快方法。 【参考方案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 然后查询文档。

以上是关于Mongodb:基于 ISODate 格式的时间查询的主要内容,如果未能解决你的问题,请参考以下文章

如何在 mongodb php 中以 ISODATE 格式存储当前日期和时间?

mongodb isodate怎么查询

将 MongoDB 字段从字符串转换为数组中的 ISODate

mongodb对数组元素及内嵌文档进行增删改查操作(转)

mongoDB对时间的处理ISODate与我们时区相差8小时

golang解析mongodb中的ISODate类型