Tuvimos un problema relacionado con los datos duplicados en nuestra base de datos, con un campo de fecha con múltiples valores donde debíamos tener 1. Pensé en agregar la forma en que resolvimos el problema como referencia.
Tenemos una colección llamada "datos" con un campo numérico de "valor" y un campo de fecha "fecha". Tuvimos un proceso que pensamos que era idempotente, pero terminamos agregando 2 valores por día en la segunda ejecución:
{ "_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")}
Solo necesitamos 1 de los 2 registros, por lo que tuvimos que recurrir al javascript para limpiar la base de datos. Nuestro enfoque inicial sería iterar a través de los resultados y eliminar cualquier campo con un tiempo entre las 6 a.m. y las 11 a.m. (todos los duplicados eran por la mañana), pero durante la implementación, se realizó un cambio. Aquí está la secuencia de comandos utilizada para solucionarlo:
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;
}
}
y luego lo ejecuté con mongo thedatabase fixer_script.js