2015-05-12 12 views
15

In der Dokumentation für MongoDB heißt es: "Geändert in Version 3.0: Die Option dropDups ist nicht mehr verfügbar."Mongo 3 Duplikate auf eindeutigen Index - dropDups

Gibt es etwas, was ich tun kann (außer Downgrade), wenn ich tatsächlich einen eindeutigen Index erstellen und doppelte Einträge zerstören möchte?

Bitte beachten Sie, dass ich etwa 300 Einträge pro Sekunde erhalte, so dass ich nicht einfach alle Duplikate löschen kann und hoffe, dass bis zum Abschluss der Indizierung keine kommen wird.

+0

Ich verstehe Ihre Frage nicht. Ist es richtig, dass Sie bereits vorhandene Dokumente haben, einschließlich Duplikate, und jetzt möchten Sie einen eindeutigen Index auf das Feld legen, der Duplikate kontaktiert, während gleichzeitig neue potenzielle Betrogene kommen? –

+1

ja. Ich möchte die Dups loswerden und wenn neue kommen, lehne sie ab. – Alonzorz

+0

Ich bin mit diesem Problem auch geblieben, gibt es eine Alternative, wie man Dubletten ohne 'dropDups' in MongoDB> = 3 loswerden kann. –

Antwort

11

Ja dropDupes ist jetzt deprecated seit Version 2.7.5, da nicht korrekt vorhergesagt werden konnte, welches Dokument dabei gelöscht würde.

Typischerweise haben Sie 2 Möglichkeiten:

  1. eine neue Kollektion Verwendung:

    • eine neue Sammlung erstellen,
    • Erstellen Sie den eindeutigen Index auf dieser neuen Kollektion,
    • Run ein Stapel, um alle Dokumente aus der alten Sammlung in die neue zu kopieren und sicherzustellen, dass Sie doppelte Schlüsselfehler während des Vorgangs ignorieren.
  2. Abkommen mit ihm in Ihrer eigenen Sammlung von Hand:

    • stellen Sie sicher, Sie werden nicht mehr duplizierten Dokumente in Ihren Code einfügen,
    • eine Charge auf Ihrer Sammlung ausführen, um die Duplikate zu löschen (und stellen Sie sicher, dass Sie die gute behalten, wenn sie nicht vollständig identisch sind),
    • dann fügen Sie den eindeutigen Index hinzu.

Für Ihren speziellen Fall würde ich die erste Option aber mit einem Trick empfehlen:

  • eine neue Kollektion mit eindeutigem Index erstellen,
  • Code aktualisieren, so dass Sie jetzt Einfügen von Dokumenten in beide Tabellen,
  • Führen Sie einen Stapel, um alle Dokumente aus der alten Sammlung auf die neue zu kopieren (ignorieren d Schlüsselfehler),
  • benennen Sie die neue Sammlung so um, dass sie dem alten Namen entspricht.
  • Wieder aktualisieren Sie Ihren Code, so dass Sie jetzt nur noch in der „alten“ Sammlung
+1

Option 1 ist wahrscheinlich auch der beste Weg, um Indizes neu zu erstellen, da ein Live-System auf die Wiederherstellung von Indizes warten muss, was es verlangsamen kann. – Pykler

+0

'Stellen Sie sicher, dass Sie doppelte Schlüsselfehler während des Prozesses ignorieren. Wie würden Sie das tun? Es scheint, die Fehler stoppen die Transaktion Mitte Prozess – Quest

+1

Verwenden Sie MongoDB ungeordnete Masseneinfügungen: "Wenn ein Fehler während der Verarbeitung einer der Schreibvorgänge auftritt, wird MongoDB weiterhin die verbleibenden Schreibvorgänge in der Liste verarbeiten." Beispiel: db.persons.insert ([{"_ id": "Bob"}, {"_id": "John"}, {"_id": "Bob"}, {"_id": "Marc"}] , {ordered: false}) fügt 3 Dokumente ein und zeigt einen doppelten Schlüsselfehler. Mit {ordered: true} würden nur die ersten 2 eingefügt. Mehr doc [hier] (https://docs.mongodb.com/manual/reference/method/db.collection.initializeUnorderedBulkOp/#db.collection.initializeUmorderedBulkOp) –

6

Wie hervorgehoben durch @ Maxime-Beugnet schreiben können Sie eine Batch-Skript erstellen Duplikate aus einer Sammlung zu entfernen. Ich habe unten meinen Ansatz aufgenommen, der relativ schnell ist, wenn die Anzahl der Duplikate im Vergleich zur Sammlungsgröße klein ist.Zu Demonstrationszwecken wird dieses Skript Deduplizierung die Sammlung durch das folgende Skript erstellt:

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; 
} 

Sie können die Duplikate in dieser Sammlung entfernen, indem ein Aggregat Abfrage zu schreiben, die alle Datensätze mit mehr als einem Duplikat zurückgibt.

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

Mit dem Cursor können Sie dann über die doppelte Datensätze durchlaufen und Ihre eigene Business-Logik implementieren, welche der Duplikate zu entscheiden, zu entfernen. Im Beispiel unten Ich bin einfach halte das erste Vorkommen:

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

Nach dem Entfernen der Duplikate können Sie einen eindeutigen Index hinzu:

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

pip mongo_remove_duplicate_indexes installiert

besten Weg wird Um ein Python-Skript oder in einer anderen Sprache zu erstellen, iterieren Sie die Auflistung, erstellen Sie eine neue Auflistung mit einem eindeutigen Index, der auf "True" gesetzt ist, mit db.collectionname.createIndex ({'inde xname ': 1}, unique: true), und fügen Sie Ihre Dokumente aus der vorherigen Sammlung in neue Sammlung und da Schlüssel wollte eindeutig sein oder Dubletten entfernt werden nicht in der neuen Sammlung eingefügt und Sie können die Exception leicht mit Ausnahme umgehen Handhabung

Überprüfen Sie den Paketquellcode für das Beispiel