2016-12-30 9 views
1

私の文書の価格情報をprices[]配列にコピーしたいと思います。1つのフィールドを配列の最初のオブジェクトに一括してコピーし、MongoDBでドキュメントを更新する方法は?

var entitiesCol = db.getCollection('entities'); 
entitiesCol.find({"type": "item"}).forEach(function(item){ 
    item.prices = [ { 
     "value": item.price 
    }]; 
    entitiesCol.save(item); 
}); 

時間がかかり、一部のフィールドは更新されません。

私はMongooseをサーバー側で使用していますが、私も使用できます。

どうすればいいですか?

+0

あなたのMongooseとMongoDBのバージョンは? – chridam

+0

MongoDB 3.2.11おそらく – Burak

答えて

1

mongoシェルでは、メソッドを使用して、更新を迅速かつ効率的に実行できます。次の例を考えてみましょう:あなたのコレクションが大きい場合には上記

var entitiesCol = db.getCollection('entities'), 
    counter = 0, 
    ops = []; 
entitiesCol.find({ 
    "type": "item", 
    "prices.0": { "$exists": false } 
}).snapshot().forEach(function(item){ 
    ops.push({ 
     "updateOne": { 
      "filter": { "_id": item._id }, 
      "update": { 
       "$push": { 
        "prices": { "value": item.price } 
       } 
      } 
     } 
    }); 
    counter++; 

    if (counter % 500 === 0) { 
     entitiesCol.bulkWrite(ops); 
     ops = []; 
    } 
}) 

if (counter % 500 !== 0) 
    entitiesCol.bulkWrite(ops); 

counter変数は、効果的にあなたの一括更新を管理することがあります。これにより、更新操作をバッチ処理することができ、500回のリクエストでサーバーにすべてのリクエストを送信しないので、パフォーマンスが向上します。

一括操作の場合、MongoDBはバッチごとにdefault internal limit of 1000個の操作を課すため、MongoDBにデフォルトを課すよりもバッチサイズを制御できる点で500個の文書を選択するのが良い1000件以上の文書

+1

snapshot()を使うべきでしょうか? – Burak

+0

@Burak確かに、それは非共有コレクションであり、 'snapshot()'が挿入や削除からの分離を保証していないことに留意してください。 – chridam

+0

私は価格の配列にプッシュしたくない場合はどうすればいいですか?私はただそれを設定したい。これを2回目に実行すると、配列に重複した価格がつきます。 – Burak

関連する問題