2017-05-10 4 views
1

存在するmongodbドキュメントのフィールドを更新したい。しかし、設定値は古い値と新しい値の平均値でなければなりません。pongongoでMongoドキュメントの平均値に更新

mongodbドキュメントから古い値を取得して平均値を計算してフィールドに設定できますが、スレッドセーフではなく、mongodbドキュメントの古い値が平均を計算する間に変更される可能性があります。

例、文書:

{ '_id':のObjectId( "55d49338b9796c337c894df3")、 値:10}

Pythonコード:

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

前:

{ '_id':のObjectId( "55d49338b9796c337c894df3")、 値:12.5}

答えて

1

あなたは更新を行うために、集約フレームワークを使用することができます。これに必要なパイプラインのステップは、$addFields$outです。 $addFieldsオペレータを使用すると、平均値を計算するために、算術演算子$avgを伴うだろう 表現、の結果と、コレクション内の既存のフィールドを置き換えることができます。

$avgオペレータ、$project(又は$addFields)段階で使用される場合、式のリストを受け入れることができるし、そのリストを使用すると、既存のフィールドと平均値を計算するための新しい値から値をプッシュすることができ これら2つの

$outオペレータを最終段階として、集約パイプラインの結果のドキュメントをコレクションに書き込むときに、既存のコレクションを更新します。これは、スレッドセーフである

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

として$projectを用い

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

またはMongoDBの3.2:

次の例では、集約操作を装っ上記更新動作を説明しますか? – deniska369

+1

'aggregate()'操作は[読み取りロック](https://docs.mongodb.com/manual/faq/concurrency/#which-operations-lock-the-database)を使用しており、あなたの質問はBlakes Seven [回答](http://stackoverflow.com/a/31837306)。 – chridam

+1

@chridam残念ながら、このアプローチはうまくいきません.MongoDB 3.4では、既存のコレクションへの更新を行うために集約フレームワークを使用することはできません。 '$ out'演算子は[現在のデータベースに新しいコレクションを作成する](https://docs.mongodb.com/manual/reference/operator/aggregation/out/#create-new-collection)既に存在していない場合)、または[**ターゲットコレクションが既に存在する場合はそれを置き換える](https:// docs。mongodb.com/manual/reference/operator/aggregation/out/#replace-existing-collection)。 – Stennie

関連する問題