web-dev-qa-db-ja.com

mongo 3は一意のインデックスで重複しています-dropDups

MongoDBのドキュメントには、「バージョン3.0で変更:dropDupsオプションは使用できなくなりました」と書かれています。

一意のインデックスを実際に作成して重複エントリを破棄したい場合、(ダウングレード以外に)何かできることはありますか?

毎秒約300の挿入を受け取るので、重複をすべて削除するだけでなく、インデックス作成が完了するまでに何も挿入されないことを期待してください。

18
Alonzorz

はいdropDupes非推奨 になりました。バージョン2.7.5以降、プロセスで削除されるドキュメントを正しく予測することができなかったためです。

通常、2つのオプションがあります。

  1. 新しいコレクションを使用:

    • 新しいコレクションを作成し、
    • この新しいコレクションに一意のインデックスを作成し、
    • バッチを実行して、すべてのドキュメントを古いコレクションから新しいコレクションにコピーし、プロセス中に重複キーエラーを無視してください。
  2. 自分のコレクションで手動で処理します。

    • コードに重複したドキュメントを挿入しないようにしてください。
    • コレクションでバッチを実行して重複を削除します(完全に同一でない場合は、適切なものを保持するようにしてください)。
    • 次に、一意のインデックスを追加します。

あなたの特定のケースでは、私は最初のオプションをお勧めしますが、トリックがあります:

  • 一意のインデックスで新しいコレクションを作成し、
  • bothテーブルにドキュメントを挿入できるようにコードを更新します。
  • バッチを実行して、古いコレクションから新しいコレクションにすべてのドキュメントをコピーします(重複キーエラーは無視してください)。
  • 古いコレクションと一致するように新しいコレクションの名前を変更します。
  • コードを再更新して、「古い」コレクションのみに書き込むようにします
15
Maxime Beugnet

@ Maxime-Beugnetで強調表示されているように、コレクションから重複を削除するバッチスクリプトを作成できます。重複の数がコレクションのサイズと比較して少ない場合は、比較的高速なアプローチを以下に含めました。デモの目的で、このスクリプトは次のスクリプトによって作成されたコレクションの重複を排除します。

db.numbers.drop()

var counter = 0
while (counter<=100000){
  db.numbers.save({"value":counter})
  db.numbers.save({"value":counter})
  if (counter % 2 ==0){
    db.numbers.save({"value":counter})
  }
  counter = counter + 1;
}

このコレクションの重複を削除するには、複数の重複を持つすべてのレコードを返す集計クエリを記述します。

var cur = db.numbers.aggregate([{ $group: { _id: { value: "$value" }, uniqueIds: { $addToSet: "$_id" }, count: { $sum: 1 } } }, { $match: { count: { $gt: 1 } } }]);

カーソルを使用すると、重複するレコードを反復処理し、独自のビジネスロジックを実装して、削除する重複を決定できます。以下の例では、最初の発生をそのまま保持しています。

while (cur.hasNext()) {
    var doc = cur.next();
    var index = 1;
    while (index < doc.uniqueIds.length) {
        db.numbers.remove(doc.uniqueIds[index]);
        index = index + 1;
    }
}

重複を削除した後、一意のインデックスを追加できます。

db.numbers.createIndex( {"value":1},{unique:true})
9
Alex

pip install mongo_remove_duplicate_indexes

最適な方法は、pythonスクリプトまたは任意の言語で作成し、コレクションを反復し、一意のインデックスをtrueに設定して新しいコレクションを作成しますdb.collectionname.createIndex( {'indexname':1}、unique:true)、そして前のコレクションから新しいコレクションにドキュメントを挿入します。区別したいキーや重複を削除したいキーは新しいコレクションに挿入されず、uは処理できます例外処理で簡単にエクスセプション

サンプルのパッケージソースコードを確認してください。

0
user7106300