需要MongoDB集合中的最大值及其时间戳

时间:2015-09-12 01:09:00

标签: mongodb mongodb-query aggregation-framework

考虑一个由以下形式的文档组成的集合:

{
"_id" : ObjectId("55f3600da9fb6e4f937a50a7"),
"timestamp" : ISODate("2010-01-01T08:10:00Z"),
"temperature" : 12.31
}
{
"_id" : ObjectId("55f3600da9fb6e4f937a50a8"),
"timestamp" : ISODate("2010-01-01T08:15:00Z"),
"temperature" : 12.48
}
...

我想找到一年中每一天的最高温度,它发生的时间。第一部分很容易使用管道聚合:

[{"$group" : {"_id" : {"day": { "$dayOfYear": "$timestamp" }},
              "max_temperature": {"$max" : "$temperature"}}},
 {"$sort" : {"_id.day":1}}]

这给了我一个很好的结果集,每天的最高温度:

{u'max_temperature': 20.98, u'_id': {u'day': 1}}
{u'max_temperature': 24.15, u'_id': {u'day': 2}}
{u'max_temperature': 22.02, u'_id': {u'day': 3}}
...

但是,如何获得每日最大值出现时的时间戳? 类似的东西:

{u'max_temperature': 20.98, u'time_of_max': ISODate("2010-01-01T15:11:12"), u'_id': {u'day': 1}}
{u'max_temperature': 24.15, u'time_of_max': ISODate("2010-01-02T16:03:42"), u'_id': {u'day': 2}}
{u'max_temperature': 22.02, u'time_of_max': ISODate("2010-01-03T16:33:59"), u'_id': {u'day': 3}}
...

2 个答案:

答案 0 :(得分:1)

首先使用$sort,使用$first运算符代替$max。但问题是你需要" day"细节减少首先出现:

[
    { "$project": {
        "day": { "$dayOfYear": "$timestamp" },
        "timestamp": 1,
        "temperature": 1
    }},
    { "$sort": { "day": 1, "temperature": -1 } },
    { "$group": {
        "_id" : "$day",
        "max_temperature": { "$first": "$temperature" },
        "timestamp": { "$first": "$timestamp" }
    }},
    { "$sort": { "_id":1 } }
]

一旦你有" day"那么输入可以在白天以最大的温度排序"价值第一。然后,$first分组运算符将从"第一个"中选择字段。在分组边界上找到的文件。

所以"温度"是"最大"因为排序顺序,其他字段将来自发生该值的同一文档。

从技术上讲,这应该仍然有效:

[
    { "$sort": { "temperature": -1, "timestamp": 1 } },
    { "$group": {
        "_id" : { "$dayOfYear": "$timestamp" },
        "max_temperature": { "$first": "$temperature" },
        "timestamp": { "$first": "$timestamp" }
    }},
    { "$sort": { "_id":1 } }
]

但由于初始排序顺序实际上与分组键不对齐,因此整体效率可能会下降。

答案 1 :(得分:0)

  

db.temp.aggregate([{$项目:{日期:{$ DAYOFYEAR: “$时间戳”},温度:“$ temperatur   E”,ISODate: “$时间戳”}},{$组:{_ ID: “$日期”,maxtemp:{ “$最大”: “$ TEMP”},timestam   号码:{ “$第一”: “$ ISODate”}}},{ “$排序”:{_ ID:1}}])