考虑一个由以下形式的文档组成的集合:
{
"_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}}
...
答案 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}}])