简体   繁体   中英

Update to average value in Mongo document with pymongo

I want to update field in exists mongodb document. But set value should be average value of old value and new value.

I can get old value from mongodb document and calculate average value, and set into field, but it's not thread safety and old value in mongodb document might change while I calculate average.

Example, document:

{ '_id': ObjectId("55d49338b9796c337c894df3"), value: 10 }

Python code:

# new_value = 15, therefore average_value = 12.5
db.mycollection.update_one(
    {'_id': '55d49338b9796c337c894df3'},
    {...} <- What there?
)

Before:

{ '_id': ObjectId("55d49338b9796c337c894df3"), value: 12.5 }

You can use the aggregation framework to do update. The pipeline steps you need for this are $addFields and $out . The $addFields operator allows you to replace an existing fields within the collection with results from an expression, which would involve the arithmetic operator $avg to compute the average.

The $avg operator, if used in the $project (or $addFields ) stage, can accept a list of expressions and with that list you can push values from the existing field and the new value for computing the average of these two.

The $out operator as the final stage will update the existing collection as it writes the resulting documents of the aggregation pipeline to a collection.

The following example describes the above update operation disguised as an aggregate operation:

new_value = 15
db.mycollection.aggregate([
    { "$addFields": {
        "value": { "$avg":  ["$value", new_value] }
    } },
    { "$out": "mycollection" }
])

or with MongoDB 3.2 using $project as

new_value = 15
db.mycollection.aggregate([
    { "$project": {
        "value": { "$avg":  ["$value", new_value] }
    } },
    { "$out": "mycollection" }
])

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM