2017-05-24 5 views
2

mongoで重複を削除するためのスクリプトを使用していますが、これはテストとして使用した10項目のコレクションで機能しましたが、私はerroを取得します。

これは私がRobomongoで実行したスクリプトです:

var bulk = db.getCollection('RAW_COLLECTION').initializeOrderedBulkOp(); 
var count = 0; 

db.getCollection('RAW_COLLECTION').aggregate([ 
    // Group on unique value storing _id values to array and count 
    { "$group": { 
    "_id": { RegisterNumber: "$RegisterNumber", Region: "$Region" }, 
    "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.getCollection('RAW_COLLECTION').initializeOrderedBulkOp(); // re-init after execute 
    } 
}); 

// Clear any queued operations 
if (count % 500 != 0) 
    bulk.execute(); 

これはERROメッセージです:

Error: command failed: { 
    "errmsg" : "exception: Exceeded memory limit for $group, but didn't allow external sort. Pass allowDiskUse:true to opt in.", 
    "code" : 16945, 
    "ok" : 0 
} : aggregate failed : 
[email protected]/mongo/shell/utils.js:23:13 
[email protected]/mongo/shell/assert.js:13:14 
[email protected]/mongo/shell/assert.js:266:5 
[email protected]/mongo/shell/collection.js:1215:5 
@(shell):1:1 

は、だから私は仕事にallowDiskUse:trueを設定する必要がありますか?スクリプトのどこでそれを行うのですか?それを行う際に危険な問題はありますか?

答えて

9
{ allowDiskUse: true } 

アグリゲーションパイプラインの直後に配置する必要があります。

あなたのコードでは、これは次のように行く必要があります。

db.getCollection('RAW_COLLECTION').aggregate([ 
    // Group on unique value storing _id values to array and count 
    { "$group": { 
    "_id": { RegisterNumber: "$RegisterNumber", Region: "$Region" }, 
    "ids": { "$push": "$_id" }, 
    "count": { "$sum": 1 }  
    }}, 
    // Only return things that matched more than once. i.e a duplicate 
    { "$match": { "count": { "$gt": 1 } } } 
], { allowDiskUse: true }) 
+0

実際に設定するのは安全ですか? これがなぜ必要なのか理解できませんでした – kadzu

+0

集約パイプラインステージの最大メモリ使用制限があります。大きなデータセットを処理するには、allowDiskUseオプションをtrueに設定して、一時ファイルにデータを書き込むことができるようにします。これは、メモリから完全に読み出すときと比べて、さまざまなパフォーマンスを与えるはずです。また、データセットのサイズにも依存します – Astro

0

From MongoDB Docs

$グループステージは、RAMの100メガバイトの制限があります。デフォルトでは、 のステージがこの制限を超えた場合、$ groupはエラーを生成します。ただし、大きなデータセットの処理を許可するには を許可するには、allowDiskUse オプションをtrueに設定して、$ group操作で一時ファイル に書き込むことができるようにします。詳細は、db.collection.aggregate()メソッドおよび集約コマンド を参照してください。

関連する問題