Удалить дубликаты из базы данных MongoDB 4.2 - PullRequest
0 голосов
/ 16 октября 2019

Я пытаюсь удалить дубликаты из MongoDB, но все решения не удаются. Моя структура JSON:

{
    "_id" : ObjectId("5d94ad15667591cf569e6aa4"),
    "a" : "aaa",
    "b" : "bbb",
    "c" : "ccc",
    "d" : "ddd",
    "key" : "057cea2fc37aabd4a59462d3fd28c93b"

}

Значение ключа - md5 (a + b + c + d). У меня уже есть база данных с более чем 1 миллиардом записей, и я хочу удалить все дубликаты в соответствии с ключом и уникальным индексом после использования, поэтому, если ключ уже находится в базе данных, запись не будет вставлена ​​снова.

Я уже пробовал

db.data.ensureIndex( { key:1 }, { unique:true, dropDups:true } )

Но для того, что я понимаю, dropDups были удалены в MongoDB> 3.0.

Я попробовал также несколько кодов java-скриптов, таких как:

var duplicates = [];

db.data.aggregate([
  { $match: { 
    key: { "$ne": '' }  // discard selection criteria
  }},
  { $group: { 
    _id: { key: "$key"}, // can be grouped on multiple properties 
    dups: { "$addToSet": "$_id" }, 
    count: { "$sum": 1 } 
  }}, 
  { $match: { 
    count: { "$gt": 1 }    // Duplicates considered as count greater than one
  }}
],
{allowDiskUse: true}       // For faster processing if set is larger
).forEach(function(doc) {
    doc.dups.shift();      // First element skipped for deleting
    doc.dups.forEach( function(dupId){ 
        duplicates.push(dupId);   // Getting all duplicate ids
        }
    )    
})

, и это не удалосьс:

QUERY [Js] uncaught exception: Error: command failed: {
“ok“: 0,
“errmsg“ : “assertion src/mongo/db/pipeline/value.cpp:1365“.
“code“ : 8,
“codeName" : “UnknownError“
} : aggregate failed

Я не изменил настройки MongoDB, работая с настройками по умолчанию.

1 Ответ

0 голосов
/ 16 октября 2019

Это моя входная коллекция dups, с некоторыми дублирующимися данными (k со значениями 11 и 22):

{ "_id" : 1, "k" : 11 }
{ "_id" : 2, "k" : 22 }
{ "_id" : 3, "k" : 11 }
{ "_id" : 4, "k" : 44 }
{ "_id" : 5, "k" : 55 }
{ "_id" : 6, "k" : 66 }
{ "_id" : 7, "k" : 22 }
{ "_id" : 8, "k" : 88 }
{ "_id" : 9, "k" : 11 }

Запрос удаляет дубликаты :

db.dups.aggregate([
  { $group: { 
        _id: "$k",
        dups: { "$addToSet": "$_id" }, 
        count: { "$sum": 1 } 
  }}, 
  { $project: { k: "$_id", _id: { $arrayElemAt: [ "$dups", 0 ] } } }
] )
=>
{ "k" : 88, "_id" : 8 }
{ "k" : 22, "_id" : 7 }
{ "k" : 44, "_id" : 4 }
{ "k" : 55, "_id" : 5 }
{ "k" : 66, "_id" : 6 }
{ "k" : 11, "_id" : 9 }

Как видите, следующие повторяющиеся данные удаляются :

{ "_id" : 1, "k" : 11 }
{ "_id" : 2, "k" : 22 }
{ "_id" : 3, "k" : 11 }


Получите результаты в массиве:

var arr = db.dups.aggregate([ ...] ).toArray()

В arr есть массив документов:

[
        {
                "k" : 88,
                "_id" : 8
        },
        {
                "k" : 22,
                "_id" : 7
        },
        {
                "k" : 44,
                "_id" : 4
        },
        {
                "k" : 55,
                "_id" : 5
        },
        {
                "k" : 66,
                "_id" : 6
        },
        {
                "k" : 11,
                "_id" : 9
        }
]
...