2012-02-17 10 views
5

私はmongodbに大きなコレクション(約270万のドキュメント)があり、重複がたくさんあります。私はensureIndex({id:1}, {unique:true, dropDups:true})をコレクション上で実行しようとしました。モンゴはそれを決定する前にしばらくそれを捨てて、too many dups on index build with dropDups=trueと決めます。MongoDbで重複を削除するにはどうしたらいいですか?

インデックスを追加して重複を取り除くにはどうすればよいですか?または、逆に、mongoがインデックスを正常に構築できるようにいくつかのdupを削除するにはどうすればよいでしょうか?

ボーナスポイントの場合、ドロップできるダップの数に制限があるのはなぜですか?

+0

オプションとして: 'id'ごとに発生数を数えるmap/reduceを実行します。次に、この結果セットを歩き、重複を持つ各 'id'に対して最初のレコードを削除します。 –

答えて

5

ボーナスポイントの場合、ドロップできるダップの数に制限があるのはなぜですか?

MongoDBはこれを防御するためにこれを行う可能性が高いです。間違ったフィールドにdropDupsがあると、データセット全体をホースし、削除操作(書き込みと同じくらい高価です)でDBをロックダウンすることができます。

インデックスを追加して重複を取り除くにはどうすればよいですか?

最初の質問は、idフィールドにユニークなインデックスを作成する理由です。

MongoDBは、のインデックスを自動的に作成するデフォルトの_idフィールドを作成します。デフォルトでMongoDBは_idObjectIdを設定しますが、好きな値でこれを上書きすることができます。 ID値の準備ができている場合は、を使用できます。

値を再インポートできない場合は、id_idに変更して値を新しいコレクションにコピーします。古いコレクションを削除して新しいコレクションの名前を変更できます。私はこの質問に出くわした

+2

編集が必要です! MongoDB> = 3の変更により* –

3

「あまりにも多くのDUP」の回避策を見つけようとしながら、(問題を(あなたは「重複キーエラー」の束を取得しますノートでは、そのあなたのコードの漁獲量を確保し、それらにを無視します)ソースからコレクションを再作成することなく)。私は最終的にそれをやった方法は、新しいコレクションc2を作成することである、(純粋にスピードアップ目的のために)必要なフィールド(複数可)に一意索引を追加し、アップサートやって:

db.c1.find().forEach(function(x){db.c2.update({field1:x.field1, field2:x.field2}, x, {upsert:true})}) 

field1の組み合わせをし、 field2は一意である必要があります。 その後、最初のコレクションc1を削除して、新しいコレクションの名前を変更することができます。このソリューションは、示されているように、1つまたは複数のフィールドで機能します。

関連する問題