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 с исключением обработки

проверьте исходный код пакета для примера