Tivemos um problema relacionado a dados duplicados em nosso banco de dados, com um campo de data com vários valores nos quais deveríamos ter 1. Pensei em adicionar a maneira como resolvemos o problema para referência.
Temos uma coleção chamada "dados" com um campo numérico "valor" e um campo de data "data". Tivemos um processo que julgamos idempotente, mas acabamos adicionando 2 x valores por dia na segunda execução:
{ "_id" : "1", "type":"x", "value":1.23, date : ISODate("2013-05-21T08:00:00Z")}
{ "_id" : "2", "type":"x", "value":1.23, date : ISODate("2013-05-21T17:00:00Z")}
Precisamos apenas de 1 dos 2 registros, portanto tivemos que recorrer ao javascript para limpar o banco de dados. Nossa abordagem inicial seria iterar os resultados e remover qualquer campo com um tempo entre 6h e 11h (todas as duplicatas eram pela manhã), mas durante a implementação, fizemos uma alteração. Aqui está o script usado para corrigi-lo:
var data = db.data.find({"type" : "x"})
var found = [];
while (data.hasNext()){
var datum = data.next();
var rdate = datum.date;
// instead of the next set of conditions, we could have just used rdate.getHour() and checked if it was in the morning, but this approach was slightly better...
if (typeof found[rdate.getDate()+"-"+rdate.getMonth() + "-" + rdate.getFullYear()] !== "undefined") {
if (datum.value != found[rdate.getDate()+"-"+rdate.getMonth() + "-" + rdate.getFullYear()]) {
print("DISCREPENCY!!!: " + datum._id + " for date " + datum.date);
}
else {
print("Removing " + datum._id);
db.data.remove({ "_id": datum._id});
}
}
else {
found[rdate.getDate()+"-"+rdate.getMonth() + "-" + rdate.getFullYear()] = datum.value;
}
}
e depois rodou com mongo thedatabase fixer_script.js