Mongo 3 дубликата по уникальному индексу - dropDups
В документации для mongoDB говорится:
"Изменено в версии 3.0: опция dropDups больше недоступна".
Есть ли что-нибудь, что я могу сделать (кроме понижения), если я действительно хочу создать уникальный индекс и уничтожить дубликаты записей?
пожалуйста, помните, что я получаю около 300 вставок в секунду, поэтому я не могу просто удалить все дубликаты и надеюсь, что к тому времени, когда я закончил индексирование, никто не войдет.
Ответы
Ответ 1
Да dropDupes
теперь устарел с версии 2.7.5, потому что невозможно было правильно предсказать, какой документ будет удален в процессе.
Как правило, у вас есть 2 варианта:
В вашем конкретном случае я бы рекомендовал первый вариант, но с трюком:
- Создайте новую коллекцию с уникальным индексом,
- Обновите свой код, чтобы теперь вы вставляли документы в таблицы и,
- Запустите пакет, чтобы скопировать все документы из старой коллекции в новую (игнорировать дублируемую ошибку ключа),
- переименуйте новую коллекцию в соответствии со старым именем.
- обновите свой код, чтобы теперь писать только в "старой" коллекции
Ответ 2
Как указано @Maxime-Beugnet, вы можете создать пакетный пакет script для удаления дубликатов из коллекции. Я включил свой подход ниже, который относительно быстр, если количество дубликатов невелико по сравнению с размером коллекции. Для демонстрационных целей этот script будет дедуплицировать коллекцию, созданную следующим script:
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})
Ответ 3
pip install mongo_remove_duplicate_indexes
лучшим способом будет создание python script или на любом языке, который вы предпочитаете, итерации коллекции, создания новой коллекции с уникальным индексом, установленным в true с помощью db.collectionname.createIndex({'indexname': 1}, unique: true) и вставьте ваши документы из предыдущей коллекции в новую коллекцию, и поскольку ключ, который вы хотите удалить или удалили, не будет вставлен в новую коллекцию ur, и вы сможете легко справиться с ecxeption с исключением обработки
проверьте исходный код пакета для примера