Mieliśmy problem ze zduplikowanymi danymi w naszej bazie danych, z polem daty zawierającym wiele wartości, w których mieliśmy mieć 1. Pomyślałem, że dodam sposób, w jaki rozwiązaliśmy ten problem w celach informacyjnych.
Mamy zbiór o nazwie „dane” z polem numerycznym „wartość” i polem „data”. Mieliśmy proces, który uważaliśmy za idempotentny, ale ostatecznie dodaliśmy 2 x wartości dziennie przy drugim uruchomieniu:
{ "_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")}
Potrzebujemy tylko 1 z 2 rekordów, więc musieliśmy skorzystać z javascript, aby wyczyścić bazę danych. Nasze początkowe podejście polegało na iteracji wyników i usunięciu dowolnego pola z czasem między 6 rano a 11 rano (wszystkie duplikaty były rano), ale podczas wdrażania wprowadzono zmianę. Oto skrypt użyty do rozwiązania tego problemu:
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;
}
}
a następnie uruchomiłem go z mongo thedatabase fixer_script.js