Het is momenteel niet mogelijk voor een update in MongoDB om te verwijzen naar de bestaande waarde van een huidig veld bij het toepassen van de update. Dus je zult moeten herhalen:
db.collection.find({},{ "category": 1 }).forEach(function(doc) {
doc.category = doc.category.trim();
db.collection.update(
{ "_id": doc._id },
{ "$set": { "category": doc.category } }
);
})
Let op het gebruik van de $set
operator daar en het geprojecteerde veld "categorie" alleen om het netwerkverkeer te verminderen"
Je zou kunnen beperken wat dat verwerkt met een $regex
overeenkomen met:
db.collection.find({
"$and": [
{ "category": /^\s+/ },
{ "category": /\s+$/ }
]
})
Of zelfs als pure $regex
zonder het gebruik van $and
die je alleen nodig hebt in MongoDB waar meerdere voorwaarden op hetzelfde veld zouden worden toegepast. Anders $and
is impliciet voor alle argumenten:
db.collection.find({ "category": /^\s+|\s+$/ })
Wat de verwerking van overeenkomende documenten beperkt tot alleen documenten met voorloop- of volgspatie.
Als u zich zorgen maakt over het aantal documenten dat u moet zoeken, zou bulkupdates moeten helpen als u MongoDB 2.6 of hoger beschikbaar heeft:
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);
Of zelfs met de API voor bulkbewerkingen voor MongoDB 2.6 en hoger:
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();
Beste gedaan met bulkWrite()
voor moderne API's die de Bulk Operations API gebruiken (technisch alles doet nu ) maar eigenlijk op een manier die veilig regressief . is met oudere versies van MongoDB. Hoewel dat in alle eerlijkheid zou betekenen vóór MongoDB 2.6 en dat u met een dergelijke versie ver buiten de dekking zou vallen voor officiële ondersteuningsopties. De codering is hiervoor wat schoner:
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 = [];
}
Die allemaal maar één keer operations naar de server sturen per 1000 documenten, of zoveel wijzigingen als u onder de 64 MB BSON-limiet past.
Als slechts een paar manieren om het probleem te benaderen. Of update eerst uw CSV-bestand voordat u het importeert.