MongoDB 查询日期范围

MongoDB query between date range

在我的 mongodb 中,字符串中的日期列。它将日期时间保存为 8/3/2020 13:50:19.

我无法进行任何日期范围查询。它返回错误的结果。

我的代码如下:

{       
                "$match": {                
                           "event.meterID.string": meter_no, 
                           "event.dataTime.string": {
                                      "$gte": prev,
                                      "$lte": dt_string
                            } 
                        } 
               }

非常感谢任何帮助。


{ "_id" : ObjectId("5f2707da47973204ce5e9d91"), "header" : { "endpointKeyHash" : { "string" : "mO5KmJVhbZMXAUrVD0uKIKf32/I=" }, "applicationToken" : { "string" : "96775772132708234336" }, "headerVersion" : { "int" : 1 }, "timestamp" : { "long" : NumberLong("1596393434007") }, "logSchemaVersion" : { "int" : 4 } }, "event" : { "meterID" : { "string" : "83.67.68.65.48.48.49.49" }, "rkw" : { "double" : -4492 }, "rkwh" : { "double" : 2 }, "rkvar" : { "double" : -2331 }, "rkv" : { "double" : 6499574 }, "rcurrent" : { "double" : 29367 }, "rhz" : { "double" : 50021 }, "rpf" : { "double" : 650 }, "ykw" : { "double" : 0 }, "ykwh" : { "double" : 0 }, "ykvar" : { "double" : 0 }, "ykv" : { "double" : 6524626 }, "ycurrent" : { "double" : 15370 }, "yhz" : { "double" : 0 }, "ypf" : { "double" : 0 }, "bkw" : { "double" : 0 }, "bkwh" : { "double" : 0 }, "bkvar" : { "double" : 0 }, "bkv" : { "double" : 6616274 }, "bcurrent" : { "double" : 34841 }, "bhz" : { "double" : 0 }, "bpf" : { "double" : 0 }, "dataTime" : { "string" : "8/3/2020 00:04:43" } } }

如评论中所述,问题在于日期存储为字符串而不是正确的 datetime 数据类型。在字符串字段上,当您使用 $lte$gte 运算符时,MongoDB 会将值作为字符串(字典顺序)而不是日期进行比较。

除了将存储的日期转换为 datetime,还有几个选项:

  1. 将日期存储为按字典顺序排序的字符串格式,例如 ISO 8601。如果日期表示为 yyyy-mm-ddThh:mm:ss,它也可以作为字符串进行比较。
  2. 创建一个聚合,在比较它们之前将字符串转换为日期对象。这对于查询来说效率不高,因为它需要在应用过滤器之前转换所有文档中的所有日期,因此不使用任何索引,但是您可以这样做:
{
  "$addFields": {
    "eventDateTime": {
      "$dateFromString": {
        "dateString": "$event.dataTime.string",
        format: "%d/%m/%Y %H:%M:%S"
      }
    }
  }
},
{
  "$match": {
    "event.meterID.string": meter_no,
    "eventDateTime": {
      "$gte": prev,
      "$lte": date_object
    }
  }
}

一般建议将日期存储为datetime字段,这样你不仅支持比较,还支持时区转换,过滤日期的子字段(例如,查找所有特定日期或月份的文档)等

更正了日期开关。否则,答案是正确的。