V současné době není možné, aby aktualizace v MongoDB odkazovala na existující hodnotu aktuálního pole při použití aktualizace. Takže budete muset opakovat:
db.collection.find({},{ "category": 1 }).forEach(function(doc) {
doc.category = doc.category.trim();
db.collection.update(
{ "_id": doc._id },
{ "$set": { "category": doc.category } }
);
})
Všimněte si použití $set
operátora a projektované pole „kategorie“ pouze za účelem snížení síťového provozu“
Co to zpracovává, můžete omezit pomocí $regex
odpovídat:
db.collection.find({
"$and": [
{ "category": /^\s+/ },
{ "category": /\s+$/ }
]
})
Nebo dokonce jako čistý $regex
bez použití $and
které potřebujete pouze v MongoDB, kde by na stejné pole bylo aplikováno více podmínek. Jinak $and
je implicitní pro všechny argumenty:
db.collection.find({ "category": /^\s+|\s+$/ })
Což omezuje zpracování odpovídajících dokumentů pouze na ty, které mají na začátku nebo na konci prázdné místo.
Pokud se obáváte počtu dokumentů, které je třeba prohlížet, měla by vám pomoci hromadná aktualizace, pokud máte k dispozici MongoDB 2.6 nebo vyšší:
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);
Nebo dokonce s API pro hromadné operace pro MongoDB 2.6 a vyšší:
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();
Nejlepší provedete pomocí bulkWrite()
pro moderní API, která používají API pro hromadné operace ( technicky vše dělá nyní ), ale ve skutečnosti způsobem, který je bezpečně regresivní se staršími verzemi MongoDB. I když ve vší upřímnosti by to znamenalo před MongoDB 2.6 a byli byste mimo pokrytí možností oficiální podpory pomocí takové verze. Kódování je proto poněkud čistší:
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 = [];
}
Které všechny odesílají operace na server pouze jednou na 1000 dokumentů nebo tolik úprav, kolik se vejde do limitu 64 MB BSON.
Jako jen několik způsobů, jak k problému přistupovat. Nebo před importem nejprve aktualizujte soubor CSV.