在MongoDB(v3.2.8)中,我以时间序列存储了一些分桶的值。我目前正在尝试使用摩洛哥框架(v1.1.0)从这些桶中聚合数据,并根据文档的日期限制文档(一个字段,见下面的示例)。
{
"_id" : ObjectId("57b696548376400e6e56a18a"),
"date" : ISODate("2016-08-19T00:00:00.000Z"),
"kpiId" : "1.2",
"history" : [
{
"name" : "02. Chilled Water Temperature",
"timestamp" : ISODate("2016-08-19T05:28:29.343Z"),
"value" : "6"
},
{
"name" : "02. Chilled Water Temperature",
"timestamp" : ISODate("2016-08-19T05:28:54.721Z"),
"value" : "1"
},
{
"name" : "02. Chilled Water Temperature",
"timestamp" : ISODate("2016-08-19T05:30:31.003Z"),
"value" : "21"
},
{
"name" : "02. Chilled Water Temperature",
"timestamp" : ISODate("2016-08-19T05:31:58.458Z"),
"value" : "20"
}
],
"asset" : {
"id" : "1",
"name" : "LTD121",
"contract" : {
"id" : "MyCompany",
"name" : "MyCompany"
}
},
"count" : 4
}
对于背景信息,我正在使用莫菲亚框架生成对MongoDB的查询。当我使用日期和kpiId
和与莫菲亚聚合时asset.contract.id
生成以下匹配查询:
{ "$match" : {
"asset.contract.id" : "MyCompany" ,
"kpiId" : "1.2",
"date" : { "$gte" : { "$date" : "2016-08-19T00:00:00.000Z"}}
}}
然而,当我期望返回示例中的文档时,此查询不会返回集合中的任何文档。当我手动将查询更改为下面的查询时,它变得更加奇怪我确实从MongoDB获取了文档。
{ "$match" : {
"asset.contract.id" : "MyCompany",
"kpiId" : "1.2" ,
"date" : { "$gte" : ISODate("2016-08-19T00:00:00.000Z")}
}}
为什么第一个查询不起作用,如果它是无效或不正确的查询,我如何操作摩洛哥以正确创建查询。
更新:每个请求添加相关的Java代码,我们使用这些代码来指示莫菲亚创建查询:
datastore.createAggregation(HistoryBucket.class)
.match(datastore.createQuery(HistoryBucket.class)
.field("asset.contract.id").equal(contractId)
.field("kpiId").equal(kpiId)
.field("date")
.greaterThanOrEq(CalendarUtils.truncateToDayUTC(startDate)))
.aggregate(HistoryBucket.class);
在这种情况下,start Date
的类型是java.util.Date
,对CalendarUtils. truncateToDayUTC
的调用的返回也返回一个java.util.Date
,分钟、小时和秒设置为0。
您的查询在Mongo Shell中不起作用的原因如下
架构中的$date存储为"date":ISODate("2016-08-19T00:00:00.000Z"),
而在聚合查询中,您将其用作String"date" : { "$gte" : { "$date":"2016-08-19T00:00:00.000Z"}}
,因此该查询不会获取任何记录,并且当您将聚合查询更改为"date" : { "$gte":ISODate("2016-08-19T00:00:00.000Z")}时,您将获得结果。
更多解释
我们在聚合管道中使用$match,我们比较的元素是"asset.contract.id"
,"kpiId"
和date
。
现在,如果我们再次指定"date" : { "$gte" : { "$date": ISODate("2016-08-19T00:00:00.000Z")}}
,我们将无法找到date.date的元素。我们不需要在$gte中指定这个$date。
最后一个问题是
db.yourCollectionName.aggregate([{ "$match" : {
"asset.contract.id" : "MyCompany",
"kpiId" : "1.2",
"date" : { "$gte" : ISODate("2016-08-19T00:00:00.000Z")}
}}])
如果您愿意,您可以使用new Date而不是ISODate,两者都会产生相同的结果,并且您还需要通过变量传递日期值。
参考文献
https://docs.mongodb.com/manual/reference/operator/query/gte/
查找两个日期之间的对象MongoDB