我想将不同的measurements
聚合到一个充当存储桶的文档中。我收到以下格式的单个测量值:
[
{
"datetime": "2020-08-03T08:00:01.648475Z",
"celsius": 20.7,
"humidity": 57
},
{
"datetime": "2020-08-03T08:05:07.756834Z",
"celsius": 18.9,
"humidity": 58
}
]
聚合存储桶应如下所示:
{
"_id": "2020-08-03",
"celsiusHigh": 20.7,
"celsiusLow": 18.9,
"firstMeasurementAt": "2020-08-03T08:00:01.648475Z",
"lastMeasurementAt": "2020-08-03T08:05:07.756834Z",
"humidityHigh": 58,
"humidityLow": 57,
"measurements": [
{
"datetime": "2020-08-03T08:00:01.648475Z",
"celsius": 20.7,
"humidity": 57
},
{
"datetime": "2020-08-03T08:05:07.756834Z",
"celsius": 18.9,
"humidity": 58
}
]
}
从MongoDB 4.2开始,我可以使用Aggregation Pipelines。但是,这些管道仅支持阶段$addFields
,$set
,$project
,$unset
,$replaceRoot
和$replaceWith
。我想使用其他更新运算符,例如$setOnInsert
(仅在插入时设置一次字段),$currentDate
(例如设置lastUpdatedAt
)或$addToSet
设置存储桶的某些字段。如果没有$addToSet
,该操作将显得很冗长:
{ $set : { "measurements": { $setUnion : [ { $ifNull: [ "$measurements", [] ] } , [ { "datetime": "2020-08-03T08:05:07.756834Z", "celsius": 18.9, "humidity": 58 } ] ] } } }
是否可以将聚合管道与更新运算符结合在一起?
答案 0 :(得分:1)
更新操作符一次仅支持单个对象的结构操作,因此您无法通过它们获得所需的结果。
但是您可以做的是利用$out
建立聚合管道db.collection.aggregate([
{
$group: {
_id: {$ArrayElemAt: [{$split: ["$datetime", "T"]}, 0]},
celsiusHigh: {$max: "$celsius"},
celsiusLow: {$min: "$celsius"},
firstMeasurementAt: {$min: "$datetime"},
lastMeasurementAt: {$max: "$datetime"},
humidityHigh: {$max: "$humidity"},
humidityLow: {$min: "$humidity"},
measurements: {$push: "$$ROOT"}
}
},
{
$out: "collection_name"
}
]);
请注意,这是基于所有datetimes
均以相同格式/时区保存的假设。没有这个,就无法完成。