Mongo不使用$ gte和$ date汇总文档

时间:2016-08-19 06:06:52

标签: mongodb mongodb-query aggregation-framework morphia mongodb-aggregation

在MongoDB(v3.2.8)中,我按时间顺序存储了一些分块值。我目前正在尝试使用Morphia框架(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
}

对于背景信息,我正在使用Morphia框架为MongoDB生成查询。当我使用日期与Morphia汇总时,kpiIdasset.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")}
}}

为什么第一个查询不起作用,如果查询无效或不正确,我如何操纵Morphia来正确创建查询。

更新:根据请求添加我们用来指示morphia创建查询的相关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);

在此startDate类型为java.util.Date,并且对CalendarUtils.truncateToDayUTC的调用返回也会返回java.util.Date,其中分钟,小时和秒设置为0。

1 个答案:

答案 0 :(得分:0)

您的查询无法在Mongo Shell中运行的原因如下

模式中的

$ date存储为@ActiveProfiles("test")

而在聚合查询中,您将其用作字符串"date" : ISODate("2016-08-19T00:00:00.000Z"),,因此查询不会获取任何记录,当您将聚合查询更改为"date" : { "$gte" : { "$date" : "2016-08-19T00:00:00.000Z"}}时,您将获得结果。

更多解释

我们在汇总管道中使用$ match,我们正在比较的元素是"date" : { "$gte" : ISODate("2016-08-19T00:00:00.000Z")}"asset.contract.id""kpiId"

现在,如果我们再次指定date,我们就会找不到date.date这样的元素。我们不需要$ gte中指定的$ date。

最终查询将是

"date" : { "$gte" : { "$date" : ISODate("2016-08-19T00:00:00.000Z")}}

如果你想要你可以使用新的日期代替ISODate,两者都会产生相同的结果,你也需要通过变量传递日期值。

<强>参考

https://docs.mongodb.com/manual/reference/operator/query/gte/

Find objects between two dates MongoDB

相关问题