2016-10-25 29 views
3

MongoDBの複数のドキュメントを1つのクエリで挿入/更新/置換する方法はありますか?MongoDBに多数のドキュメントを挿入または更新する

は、次のコレクションを想定します

[ 
    {_id: 1, text: "something"}, 
    {_id: 4, text: "baz"} 
] 

今、私はいくつかはすでにコレクションになる可能性があるの複数のドキュメントを追加したいと思います。ドキュメントがすでにコレクションに入っている場合は、それらを更新/置き換えたいと思います。クエリは、コレクションがすべき、それはまた、プロセスの後_id 1で文書を交換/更新する必要があり_id 2と3で文書を挿入する必要があり

[ 
    {_id:1, text: "something else"}, 
    {_id:2, text: "foo"}, 
    {_id:3, text: "bar"} 
] 

:たとえば、私は、次の書類を挿入したいと思います

db.collection.insertMany(
    [ {...}, {...}, {...} ], 
    { 
     ordered: false, 
    } 
) 

duplicat場合:

[ 
    {_id:1, text: "something else"}, 
    {_id:2, text: "foo"}, 
    {_id:3, text: "bar"}, 
    {_id:4, text: "baz"} 
] 

一つのアプローチはinsertManyを使用することがあります、次のように見えますその問合せは、挿入に失敗した文書の索引を含むオブジェクトの配列を含むwriteErrorsを発行します。私はそれらを通過して、代わりにそれらを更新することができます。

しかし、そのプロセスは面倒です。多くのドキュメントをという1つのクエリで挿入/更新/置換する方法はありますか?

答えて

4

としては、あなたが

script.jsにこのような何かを置くことができます必要なものを行うには、here言っ

*警告:未テストコード

use YOUR_DB 
var bulk = db.collection.initializeUnorderedBulkOp(); 
bulk.find({ _id : 1 }).upsert().update({ $set: { "text": "something else" } }); 
bulk.find({ _id : 4 }).upsert().update({ $set: { "text": "baz" } }); 
bulk.find({ _id : 99 }).upsert().update({ $set: { "text": "mrga" } }); 
bulk.execute(); 

と実行それと一緒に

mongo < script.js

これは、制限のために1000個以上のドキュメントを更新/挿入しようと試みたものがこのようにしなければならなかったためです。

書き込みコマンドは、1000を超える操作を受け入れることはできません。 mongoシェルのBulk()操作とドライバの同等のメソッドにはこの制限がありません。

source

+0

偉大です。ありがとうございました :) – str

0

次のようにデータ項目を考慮:

interface Item { 
    id: string;   // unique key across collection 
    someValue: string; 
} 

あなたが制限1000年の下のアイテムを持っている場合、あなたはこのような一括書き込み操作を行うことができます。

public async insertOrUpdateBulk(items: Item[]) { 
     try { 
      const bulkOperation = this._itemCollection.initializeUnorderedBulkOp(); 
      for (let itemIndex = 0; itemIndex < items.length; itemIndex++) { 
       const item = items[itemIndex]; 
       bulkOperation.find({ id: item.id }).upsert().update(item); 
      } 
      await bulkOperation.execute(); 
      return true; 
     } catch (err) { 
      console.log(err); 
      return false; 
     } 
    } 

の場合あなたは1000を超えるアイテムを持っている、あなたは同時に約束をすることができます:

01あなたがここにも、単一のクエリで複数のドキュメントを更新または挿入するためにBULKWRITE APIを使用することができます
public async insertOrUpdate(items: Item[]) { 
     try { 
      const promises: Array<Promise<UpdateWriteOpResult>> = []; 
      for (let itemIndex = 0; itemIndex < items.length; itemIndex++) { 
       const item = items[itemIndex]; 
       const updatePromise = this.itemCollection.updateOne({ id: item.id }, item, { upsert: true }); 
       promises.push(updatePromise); 
      } 
      await Promise.all(promises); 
      console.log('done...'); 
      return true; 
     } catch (err) { 
      console.log(err); 
      return false; 
     } 
    } 
0

var ops = [] 

items.forEach(item => { 
    ops.push(
     { 
      updateOne: { 
       filter: { _id: unique_id }, 
       update: { 
        $set: { fields_to_update_if_exists }, 
        $setOnInsert: { fileds_to_insert_if_does_not_exist } 
       }, 
       upsert: true 
      } 
     } 
    ) 
}) 

db.collections('collection_name').bulkWrite(ops, { ordered: false }); 
関連する問題