O "dropDups" a sintaxe para criação de índice foi "descontinuada" a partir do MongoDB 2.6 e removida no MongoDB 3.0. Não é uma boa ideia na maioria dos casos usar isso, pois a "remoção" é arbitrária e qualquer "duplicata" pode ser removida. O que significa que o que é "removido" pode não ser o que você realmente deseja remover.
De qualquer forma, você está se deparando com um erro de "comprimento do índice", pois o valor da chave de índice aqui seria mais longo do que o permitido. De um modo geral, você não está "destinado" a indexar 43 campos em qualquer aplicativo normal.
Se você deseja remover os "duplicados" de uma coleção, sua melhor aposta é executar uma consulta de agregação para determinar quais documentos contêm dados "duplicados" e, em seguida, percorrer essa lista removendo "todos, exceto um" dos já "únicos"
_id
valores da coleção de destino. Isso pode ser feito com operações "em massa" para máxima eficiência. OBSERVAÇÃO :Acho difícil acreditar que seus documentos realmente contenham 43 campos "únicos". É provável que "tudo que você precisa" é simplesmente identificar somente os campos que tornam o documento "único" e, em seguida, siga o processo conforme descrito abaixo:
var bulk = db.testkdd.initializeOrderedBulkOp(),
count = 0;
// List "all" fields that make a document "unique" in the `_id`
// I am only listing some for example purposes to follow
db.testkdd.aggregate([
{ "$group": {
"_id": {
"duration" : "$duration",
"protocol_type": "$protocol_type",
"service": "$service",
"flag": "$flag"
},
"ids": { "$push": "$_id" },
"count": { "$sum": 1 }
}},
{ "$match": { "count": { "$gt": 1 } } }
],{ "allowDiskUse": true}).forEach(function(doc) {
doc.ids.shift(); // remove first match
bulk.find({ "_id": { "$in": doc.ids } }).remove(); // removes all $in list
count++;
// Execute 1 in 1000 and re-init
if ( count % 1000 == 0 ) {
bulk.execute();
bulk = db.testkdd.initializeOrderedBulkOp();
}
});
if ( count % 1000 != 0 )
bulk.execute();
Se você tiver uma versão do MongoDB "inferior" a 2.6 e não tiver operações em massa, tente com o padrão
.remove()
dentro do laço também. Observando também que .aggregate()
não retornará um cursor aqui e o loop deve mudar para:db.testkdd.aggregate([
// pipeline as above
]).result.forEach(function(doc) {
doc.ids.shift();
db.testkdd.remove({ "_id": { "$in": doc.ids } });
});
Mas certifique-se de examinar seus documentos de perto e incluir apenas "apenas" os campos "únicos" que você espera que façam parte do agrupamento
_id
. Caso contrário, você acaba não removendo nada, pois não há duplicatas lá.