Jak podkreślił @ Maxime-Beugnet można utworzyć skrypt wsadowy, aby usunąć duplikaty z kolekcji. Zawarłem poniższe podejście, które jest stosunkowo szybkie, jeśli liczba duplikatów jest niewielka w porównaniu do rozmiaru kolekcji.Dla celów demonstracyjnych ten skrypt de-powielać kolekcję stworzoną przez następujący skrypt:
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;
}
można usunąć duplikaty z tej kolekcji pisząc zapytanie zbiorczą, która zwraca wszystkie rekordy z więcej niż jednego duplikatu.
var cur = db.numbers.aggregate([{ $group: { _id: { value: "$value" }, uniqueIds: { $addToSet: "$_id" }, count: { $sum: 1 } } }, { $match: { count: { $gt: 1 } } }]);
Za pomocą kursora można następnie iteracyjne ciągu zduplikowanych rekordów i zaimplementować własną logikę biznesową, aby zdecydować, które z duplikatów usunąć. W przykładzie poniżej Ja po prostu utrzymując pierwsze wystąpienie:
while (cur.hasNext()) {
var doc = cur.next();
var index = 1;
while (index < doc.uniqueIds.length) {
db.numbers.remove(doc.uniqueIds[index]);
index = index + 1;
}
}
Po usunięciu duplikatów można dodać unikatowy indeks:
db.numbers.createIndex({"value":1},{unique:true})
Nie rozumiem twojego pytania. Czy mam rację, że masz już istniejące dokumenty, w tym duplikaty, a teraz chcesz umieścić unikalny indeks w polu, kontaktując się z duplikatami, a jednocześnie pojawiają się potencjalne nowe oszustwa? –
tak. Chcę pozbyć się dupków i jeśli pojawią się nowe, odrzuć je. – Alonzorz
Utknąłem również z tym problemem, czy jest jakakolwiek alternatywa, jak pozbyć się duplikatów bez 'dropDups' w MongoDB> = 3. * ?? –