Det är för närvarande inte möjligt för en uppdatering i MongoDB att referera till det befintliga värdet för ett aktuellt fält när uppdateringen tillämpas. Så du kommer att behöva loopa:
db.collection.find({},{ "category": 1 }).forEach(function(doc) {
doc.category = doc.category.trim();
db.collection.update(
{ "_id": doc._id },
{ "$set": { "category": doc.category } }
);
})
Notera användningen av $set
operatör där och det projicerade fältet "kategori" endast för att minska nätverkstrafiken"
Du kan begränsa vad som bearbetas med en $regex
att matcha:
db.collection.find({
"$and": [
{ "category": /^\s+/ },
{ "category": /\s+$/ }
]
})
Eller till och med som ren $regex
utan användning av $and
som du bara behöver i MongoDB där flera villkor skulle tillämpas på samma fält. Annars $and
är implicit för alla argument:
db.collection.find({ "category": /^\s+|\s+$/ })
Vilket begränsar de matchade dokumenten att behandla till endast de med inledande eller efterföljande blanksteg.
Om du är orolig för antalet dokument att titta på, bör massuppdatering hjälpa dig om du har MongoDB 2.6 eller senare tillgänglig:
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);
Eller till och med med bulk operations API för MongoDB 2.6 och högre:
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();
Bäst gjort med bulkWrite()
för moderna API:er som använder Bulk Operations API (tekniskt sett allt). gör nu ) men faktiskt på ett sätt som är säkert regressivt med äldre versioner av MongoDB. Fast i ärlighetens namn skulle det betyda före MongoDB 2.6 och att du skulle vara långt utanför täckning för officiella supportalternativ med en sådan version. Kodningen är något renare för detta:
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 = [];
}
Som alla bara skickar operationer till servern en gång per 1000 dokument, eller så många ändringar du kan få plats under 64 MB BSON-gränsen.
Som bara några sätt att närma sig problemet. Eller uppdatera din CSV-fil innan du importerar.