[英]MongoDB | Update rows record by record on basis of one field
我想根據時間范圍使用溫度的min
/ max
/ avg
更新 python 中 mongodb 中集合的文檔/記錄。
在下面的示例中,假設給我的時間范圍是“20:09-20:15”,那么最后一行將不會更新,其余行會更新。
樣本數據:
[
{'date': "1-10-2020", 'time': "20:09", 'temperature': 20}, //1
{'date': "1-10-2020", 'time': "20:11", 'temperature': 19}, //2
{'date': "1-10-2020", 'time': "20:15", 'temperature': 18}, //3
{'date': "1-10-2020", 'time': "20:18", 'temperature': 18} //4
]
所需輸出:
[
{'date': "1-10-2020", 'time': "20:09", 'temperature': 20, 'MIN': 20, 'MAX': 20, 'AVG': 20}, //1
{'date': "1-10-2020", 'time': "20:11", 'temperature': 19, 'MIN': 19, 'MAX': 20, 'AVG': 19.5}, //2
{'date': "1-10-2020", 'time': "20:15", 'temperature': 18, 'MIN': 18, 'MAX': 20, 'AVG': 19}, //3
{'date': "1-10-2020", 'time': "20:18", 'temperature': 18} //4
]
如果您使用的是 Mongo 4.4+ 版,則可以使用$merge使用管道來實現此目的:
db.collection.aggregate([
{
$match: {
time: {
$gte: "20:09",
$lte: "20:15"
}
}
},
{
$group: {
_id: null,
avg: {
$avg: "$temperature"
},
min: {
$min: "$temperature"
},
max: {
$max: "$temperature"
},
root: {
$push: "$$ROOT"
}
}
},
{
$unwind: "$root"
},
{
"$replaceRoot": {
"newRoot": {
"$mergeObjects": [
"$root",
{
"MIN": "$min",
"MAX": "$max",
"AVG": "$avg"
}
]
}
}
},
{
$merge: {
into: "collection",
on: "_id",
whenMatched: "replace"
}
}
])
如果您使用的是較小的 Mongo 版本,則必須將其拆分為 2 個調用,首先使用相同的$group
階段來獲取結果,然后使用這些值進行更新:你正在使用pymongo
)
results = list(collection.aggregate([
{
"$match": {
"time": {
"$gte": "20:09",
"$lte": "20:15"
}
}
},
{
"$group": {
"_id": None,
"avg": {
"$avg": "$temperature"
},
"min": {
"$min": "$temperature"
},
"max": {
"$max": "$temperature"
},
"root": {
"$push": "$$ROOT"
}
}
}
]))
collection.update_many(
{
"time": {
"$gte": "20:09",
"$lt": "20:15"
}
},
{
"$set": {
"MAX": results[0]["max"],
"MIN": results[0]["min"],
"AVG": results[0]["avg"],
}
}
)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.