Mongo在使用$gte和$date进行聚合时未返回文档

3

我在 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的查询。当我使用日期和kpiId以及asset.contract.id在Morphia中进行聚合时,会生成以下匹配查询:

{ "$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来正确创建查询。
更新:根据请求,添加相关的Java代码,我们使用这些代码指示morphia创建查询:
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
嗨,gerben84,欢迎来到Stack Overflow。你的问题看起来很好,有很多相关和精美呈现的信息,但是还有一件事情缺失:你能展示一下生成该聚合的morphia代码吗? - Vince Bowdren
嗨,Vince Bowdren,我已经添加了相关的Java代码,用于指示Morphia查询数据。 - user1230680
1个回答

0

你的查询在Mongo Shell中无法工作的原因如下:

模式中的 $date 存储为 "date" : ISODate("2016-08-19T00:00:00.000Z"),

而在聚合查询中,您将其用作字符串 "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中查找两个日期之间的对象


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接