Obecnie nie jest możliwe, aby aktualizacja w MongoDB odwoływała się do istniejącej wartości bieżącego pola podczas stosowania aktualizacji. Więc będziesz musiał zapętlić:
db.collection.find({},{ "category": 1 }).forEach(function(doc) {
doc.category = doc.category.trim();
db.collection.update(
{ "_id": doc._id },
{ "$set": { "category": doc.category } }
);
})
Zwracając uwagę na użycie $set
tam operatora i przewidywane pole „kategoria” tylko w celu zmniejszenia ruchu w sieci”
Możesz ograniczyć to, co przetwarza za pomocą $regex
dopasować:
db.collection.find({
"$and": [
{ "category": /^\s+/ },
{ "category": /\s+$/ }
]
})
Lub nawet jako czysty $regex
bez użycia $and
których potrzebujesz tylko w MongoDB, gdzie do tego samego pola zostanie zastosowanych wiele warunków. W przeciwnym razie $and
jest dorozumiana dla wszystkich argumentów:
db.collection.find({ "category": /^\s+|\s+$/ })
Co ogranicza dopasowane dokumenty do przetworzenia tylko do tych z początkowymi lub końcowymi białymi znakami.
Jeśli martwisz się liczbą dokumentów do przejrzenia, aktualizacja zbiorcza powinna pomóc, jeśli masz dostępną wersję MongoDB w wersji 2.6 lub nowszej:
var batch = [];
db.collection.find({ "category": /^\s+|\s+$/ },{ "category": 1 }).forEach(
function(doc) {
batch.push({
"q": { "_id": doc._id },
"u": { "$set": { "category": doc.catetgory.trim() } }
});
if ( batch.length % 1000 == 0 ) {
db.runCommand("update", batch);
batch = [];
}
}
);
if ( batch.length > 0 )
db.runCommand("update", batch);
Lub nawet z interfejsem API operacji zbiorczych dla MongoDB 2.6 i nowszych:
var counter = 0;
var bulk = db.collection.initializeOrderedBulkOp();
db.collection.find({ "category": /^\s+|\s+$/ },{ "category": 1}).forEach(
function(doc) {
bulk.find({ "_id": doc._id }).update({
"$set": { "category": doc.category.trim() }
});
counter = counter + 1;
if ( counter % 1000 == 0 ) {
bulk.execute();
bulk = db.collection.initializeOrderedBulkOp();
}
}
);
if ( counter > 1 )
bulk.execute();
Najlepsze zrobione za pomocą bulkWrite()
dla nowoczesnych interfejsów API, które używają API Bulk Operations (technicznie wszystko robi teraz ), ale w rzeczywistości w sposób bezpiecznie regresywny ze starszymi wersjami MongoDB. Chociaż, szczerze mówiąc, oznaczałoby to wcześniejsze MongoDB 2.6 i byłoby daleko poza zasięgiem oficjalnych opcji wsparcia przy użyciu takiej wersji. Kodowanie jest w tym przypadku nieco czystsze:
var batch = [];
db.collection.find({ "category": /^\s+|\s+$/ },{ "category": 1}).forEach(
function(doc) {
batch.push({
"updateOne": {
"filter": { "_id": doc._id },
"update": { "$set": { "category": doc.category.trim() } }
}
});
if ( batch.legth % 1000 == 0 ) {
db.collection.bulkWrite(batch);
batch = [];
}
}
);
if ( batch.length > 0 ) {
db.collection.bulkWrite(batch);
batch = [];
}
Które wszystkie wysyłają operacje na serwer tylko raz na 1000 dokumentów lub tyle modyfikacji, ile zmieścisz w ramach limitu 64 MB BSON.
Jako tylko kilka sposobów podejścia do problemu. Lub zaktualizuj plik CSV przed importowaniem.