【问题标题】:Mongo does not return documents in aggregation using $gte and $dateMongo 不使用 $gte 和 $date 返回聚合中的文档
【发布时间】:2016-08-19 06:06:52
【问题描述】:

在 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);

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

【问题讨论】:

  • 嗨 gerben84,欢迎来到 Stack Overflow。您的问题看起来不错,有很多相关且呈现良好的信息,但只缺少一件事:您能展示生成该聚合的 morphia 代码吗?
  • 您好 Vince Bowdren,我添加了相关的 Java 代码,用于指示 Morphia 查询数据。

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


【解决方案1】:

您的查询在 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/

Find objects between two dates MongoDB

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-01
    • 1970-01-01
    • 2019-11-30
    • 2015-02-27
    • 1970-01-01
    • 2015-05-10
    • 2017-08-31
    • 2019-07-11
    相关资源
    最近更新 更多