mongodb中使用ISODate的日期查询似乎无法工作

我似乎不能得到甚至是最基本的日期查询工作在MongoDB。使用类似这样的文档:

{
"_id" : "foobar/201310",
"ap" : "foobar",
"dt" : ISODate("2013-10-01T00:00:00.000Z"),
"tl" : 375439
}

查询如下所示:

{
"dt" : {
"$gte" : {
"$date" : "2013-10-01T00:00:00.000Z"
}
}
}

我通过执行得到0的结果:

db.mycollection.find({
"dt" : { "$gte" : { "$date" : "2013-10-01T00:00:00.000Z"}}
})

知道为什么不行吗?

作为参考,这个查询是由Spring的MongoTemplate产生的,所以我不能直接控制最终发送到MongoDB的查询。

(注:)

> db.version()
2.4.7

谢谢!

548613 次浏览

虽然$dateMongoDB扩展JSON的一部分,这是你在mongoexport中默认得到的,但我认为你不能真正将它用作查询的一部分。

如果尝试使用$date进行精确搜索,如下所示:

db.foo.find({dt: {"$date": "2012-01-01T15:00:00.000Z"}})

你会得到错误:

error: { "$err" : "invalid operator: $date", "code" : 10068 }

试试这个:

db.mycollection.find({
"dt" : {"$gte": new Date("2013-10-01T00:00:00.000Z")}
})

或(以下由@user3805045注释):

db.mycollection.find({
"dt" : {"$gte": ISODate("2013-10-01T00:00:00.000Z")}
})

ISODate也可能被要求比较没有时间的日期(由@MattMolnar标记)。

根据mongo Shell中的数据类型,两者应该是等价的:

mongo shell提供了各种方法来返回日期,可以是字符串,也可以是date对象:

  • Date()方法,该方法以字符串形式返回当前日期。
  • 新的Date()构造函数,它使用ISODate()包装器返回一个Date对象。
  • 构造函数,它使用ISODate()包装器返回一个Date对象。

和使用ISODate 还应该返回一个Date对象吗

当需要严格的JSON表示时,可以使用{"$date": "ISO-8601 string"}。一个可能的例子是Hadoop连接器。

MongoDB食谱页注释:

"dt" :
{
"$gte" : ISODate("2014-07-02T00:00:00Z"),
"$lt" : ISODate("2014-07-03T00:00:00Z")
}

这对我很管用。在完整的上下文中,以下命令获取dt date字段的日期为2013-10-01 (YYYY-MM-DD) Zulu的每一条记录:

db.mycollection.find({ "dt" : { "$gte" : ISODate("2013-10-01T00:00:00Z"), "$lt" : ISODate("2013-10-02T00:00:00Z") }})

在MongoDB shell中:

db.getCollection('sensorevents').find({from:{$gt: new ISODate('2015-08-30 16:50:24.481Z')}})

在我的nodeJS代码中(使用Mongoose)

    SensorEvent.Model.find( {
from: { $gt: new Date( SensorEventListener.lastSeenSensorFrom ) }
} )

我正在查询我的传感器事件集合,以返回'from'字段大于给定日期的值

试试这个:

{ "dt" : { "$gte" : ISODate("2013-10-01") } }

我使用robomongo作为mongodb客户端gui,下面为我工作

db.collectionName.find({"columnWithDateTime" : {
$lt:new ISODate("2016-02-28T00:00:00.000Z")}})

在应用程序方面,我使用基于nodejs的驱动程序mongodb(v1.4.3),应用程序在ui中使用datepicker,它给出日期如YYYY-mm-dd,然后附加默认时间如00:00:00,然后给new Date()构造函数,然后提供给mongodb criteria对象,我认为驱动程序将日期转换为ISO日期,然后查询工作并给出所需的输出,然而,对于相同的条件,相同的new Date()构造函数在robomongo上不工作或显示相同的输出,这很奇怪,因为我使用robomongo来交叉检查我的criteria对象。

而默认的cli mongoshell可以很好地使用ISODatenew Date()

在json严格模式下,你必须保持以下顺序:

{
"dt": {
"$gte": {
"$date": "2013-10-01T00:00:00.000Z"
}
}
}

唯一的一件事是在mlab.com上定义我的搜索查询。

这是我的文档

"_id" : ObjectId("590173023c488e9a48e903d6"),
"updatedAt" : ISODate("2017-04-27T04:26:42.709Z"),
"createdAt" : ISODate("2017-04-27T04:26:42.709Z"),
"flightId" : "590170f97cb84116075e2680",


"_id" : ObjectId("590173023c488e9a48e903d6"),
"updatedAt" : ISODate("2017-04-28T03:26:42.609Z"),
"createdAt" : ISODate("2017-04-28T03:26:42.609Z"),
"flightId" : "590170f97cb84116075e2680",

现在我想找到每一个27号日期的文档。所以我用了这个....

 > db.users.find({createdAt:{"$gte":ISODate("2017-04-27T00:00:00Z"),"$lt":ISODate("2017-04-28T00:00:00Z") }}).count()


result:1

这对我很管用。

当我在搜索小于或等于现在的值时,这个方法很管用:

db.collectionName.find({ "dt": { "$lte" : new Date() + "" } });

new Date()包装它:

{ "dt" : { "$lt" : new Date("2012-01-01T15:00:00.000Z") } }

老问题,但仍然是第一个谷歌击中,所以我张贴在这里,所以我发现它再次更容易…

使用Mongo 4.2和一个aggregate():

db.collection.aggregate(
[
{ $match: { "end_time": { "$gt": ISODate("2020-01-01T00:00:00.000Z")  } } },
{ $project: {
"end_day": { $dateFromParts: { 'year' : {$year:"$end_time"}, 'month' : {$month:"$end_time"}, 'day': {$dayOfMonth:"$end_time"}, 'hour' : 0  } }
}},
{$group:{
_id:   "$end_day",
"count":{$sum:1},
}}
]
)

这个函数将groupby变量作为日期,有时更好的方法是将其作为组件本身。

虽然我对AWS DocumentDB(应该是Mongo 4兼容)进行了测试,但这对我来说工作得很好,没有使用任何__abc0或ISODate:

db.collection_name.find({"an_iso_date_field": {$lte: "2021-02-04T03:42:00Z"}})