MongoDB |根据一个字段逐条记录更新记录

时间:2020-10-01 15:24:39

标签: python python-3.x mongodb pymongo pymongo-2.x

我想根据时间范围以温度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
]

1 个答案:

答案 0 :(得分:0)

如果您使用的是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 Playground

如果您使用的是Mongo的较低版本,则必须将其分为2个调用,首先使用相同的$group阶段来获取结果,然后使用值进行更新:(我会在其中写一个标记为您正在使用pymongo的python

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"],
        }
    }
)
相关问题