2016-05-26 9 views
5

私は最新のmongodb 3.2を持っていて、timeStampを持つ多くのアイテムのコレクションがあります。updateManyで現在のドキュメントのポインタを更新する方法

Aは、Dateオブジェクトにミリ秒を変換する必要があり、今私は、この関数を使用します。

db.myColl.find().forEach(function (doc) { 
    doc.date = new Date(doc.date); 
    db.myColl.save(doc); 
}) 

それは、行の2百万人を更新するのに非常に長い時間がかかりました。

私はupdateManyを使用しようとしています(非常に速いと思われます)が、現在のドキュメントにどのようにアクセスできますか?上記のクエリをupdateManyを使用して書き直す機会はありますか?

ありがとうございます。

+0

あなたは、クライアントとサーバの交渉の時間を節約する必要があります。 [これはあなたを助けるかもしれません。](http://stackoverflow.com/questions/8342725/multiply-field-by-value-in-mongodb/8343147#8343147) –

答えて

2

あなたは、それを操作、ドキュメントにアクセスするためのイテレータを使用し、リストに変更された文書を追加してからで更新操作のリストを送信することができますbulkWrite()法などの他の一括更新のAPIを利用することができます実行のためのバッチをサーバーに送ります。

以下は、あなたがcolloctionを反復するために、カーソルのforEach()メソッドを使用して、更新することができ、約1000のドキュメントのバッチに更新操作をプッシュすると同時に、各ドキュメントを変更あろうにこのアプローチを、実証します一度にbulkWrite()メソッドを使用します。

それは同じ基礎一括書き込み操作を使用していますので、これはupdateMany()を使っほど効率的である:

var cursor = db.myColl.find({"date": { "$exists": true, "$type": 1 }}), 
    bulkUpdateOps = []; 

cursor.forEach(function(doc){ 
    var newDate = new Date(doc.date); 
    bulkUpdateOps.push({ 
     "updateOne": { 
      "filter": { "_id": doc._id }, 
      "update": { "$set": { "date": newDate } } 
     } 
    }); 

    if (bulkUpdateOps.length == 1000) { 
     db.myColl.bulkWrite(bulkUpdateOps); 
     bulkUpdateOps = []; 
    } 
});   

if (bulkUpdateOps.length > 0) { db.myColl.bulkWrite(bulkUpdateOps); } 
1

現在のクエリは、フィールド値をそれ自体または他のフィールド値で設定する唯一の解決策です(ドキュメントから複数のフィールドを使用してデータを計算することができます)。

サーバー上でmongoシェルを直接実行すると(クライアントにデータが渡されない)、そのクエリのパフォーマンスを向上させる方法があります。

関連する問題