sql >> データベース >  >> NoSQL >> MongoDB

mongodbの重複を削除します

    他のすべての重複を単純に破棄する準備ができている場合は、基本的に .aggregate() 同じRegisterNumberでドキュメントを収集するため 最初の一致以外の他のすべてのドキュメントを評価して削除します。

    MongoDB 3.0.xにはいくつかの最新のヘルパーがありませんが、 .aggregate() プロセスの大きな結果セットと"bulkoperations"の存在のカーソルを返します 書き込みパフォーマンスはまだ存在します:

    var bulk = db.collection.initializeOrderedBulkOp();
    var count = 0;
    
    db.collection.aggregate([
      // Group on unique value storing _id values to array and count 
      { "$group": {
        "_id": "$RegisterNumber",
        "ids": { "$push": "$_id" },
        "count": { "$sum": 1 }      
      }},
      // Only return things that matched more than once. i.e a duplicate
      { "$match": { "count": { "$gt": 1 } } }
    ]).forEach(function(doc) {
      var keep = doc.ids.shift();     // takes the first _id from the array
    
      bulk.find({ "_id": { "$in": doc.ids }}).remove(); // remove all remaining _id matches
      count++;
    
      if ( count % 500 == 0 ) {  // only actually write per 500 operations
          bulk.execute();
          bulk = db.collection.initializeOrderedBulkOp();  // re-init after execute
      }
    });
    
    // Clear any queued operations
    if ( count % 500 != 0 )
        bulk.execute();
    

    最新のリリース(3.2以降)では、を使用することをお勧めします。 bullkWrite() 代わりは。上記と同じ「バルク」メソッドは実際には「内部」と呼ばれるため、これは「クライアントライブラリ」のものであることに注意してください。

    var ops = [];
    
    db.collection.aggregate([
      { "$group": {
        "_id": "$RegisterNumber",
        "ids": { "$push": "$id" },
        "count": { "$sum": 1 }      
      }},
      { "$match": { "count": { "$gt": 1 } } }
    ]).forEach( doc => {
    
      var keep = doc.ids.shift();
    
      ops = [
        ...ops,
        {
          "deleteMany": { "filter": { "_id": { "$in": doc.ids } } }
        }
      ];
    
      if (ops.length >= 500) {
        db.collection.bulkWrite(ops);
        ops = [];
      }
    });
    
    if (ops.length > 0)
      db.collection.bulkWrite(ops);
    

    したがって、 $ group $ RegisterNumberを介してすべてをまとめます 値を設定し、一致するドキュメント _idを収集します 配列への値。 $ sumを使用して、これが発生した回数をカウントします。

    次に、カウントが 1しかないドキュメントを除外します。 それらは明らかに重複していないからです。

    ループに渡すと、 _idの最初の出現を削除します .shift()を使用してキーの収集リストに 、アレイ内に他の「重複」のみを残します。

    これらは、 $in<を使用して「削除」操作に渡されます。 / code> 照合および削除するドキュメントの「リスト」として。

    他の重複ドキュメントから詳細をマージするなど、より複雑なものが必要な場合、プロセスは一般的に同じです。「一意のキー」の大文字と小文字を変換して、実際に最初に重複を削除するなどの場合は、さらに注意が必要になる場合があります。変更するドキュメントに変更を書き込む前。

    いずれにせよ、集計では実際に「重複」しているドキュメントが強調表示されます。残りの処理ロジックは、情報を特定した後、その情報を実際に処理したいことに基づいています。




    1. Mongoデータベースはマップからデータを保存します

    2. MongoDB-コレクション内のネストされたアイテムをクエリする方法は?

    3. マングースfindOneと並べ替え

    4. mongodbは値からドキュメント全体を取得します