Atualmente, não é possível que uma atualização no MongoDB faça referência ao valor existente de um campo atual ao aplicar a atualização. Então você vai ter que fazer um loop:
db.collection.find({},{ "category": 1 }).forEach(function(doc) {
doc.category = doc.category.trim();
db.collection.update(
{ "_id": doc._id },
{ "$set": { "category": doc.category } }
);
})
Observando o uso do
$set
operador lá e o campo "categoria" projetado apenas para reduzir o tráfego de rede" Você pode limitar o que isso processa com um
$regex
para corresponder:db.collection.find({
"$and": [
{ "category": /^\s+/ },
{ "category": /\s+$/ }
]
})
Ou mesmo como puro
$regex
sem o uso de $and
que você só precisa no MongoDB, onde várias condições seriam aplicadas ao mesmo campo. Caso contrário $and
está implícito a todos os argumentos:db.collection.find({ "category": /^\s+|\s+$/ })
O que restringe o processamento dos documentos correspondentes apenas àqueles com espaços em branco à esquerda ou à direita.
Se você está preocupado com o número de documentos a serem observados, a atualização em massa deve ajudar se você tiver o MongoDB 2.6 ou superior disponível:
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);
Ou mesmo com a API de operações em massa para MongoDB 2.6 e superior:
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();
Melhor feito com
bulkWrite()
para APIs modernas que usam a API de operações em massa ( tecnicamente tudo faz agora ), mas na verdade de uma forma que é regressiva com segurança com versões mais antigas do MongoDB. Embora, com toda a honestidade, isso significaria antes do MongoDB 2.6 e você estaria bem fora da cobertura das opções de suporte oficial usando essa versão. A codificação é um pouco mais limpa para isso: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 = [];
}
Todos enviam operações para o servidor apenas uma vez por 1000 documentos, ou quantas modificações você puder ajustar no limite de 64 MB BSON.
Como apenas algumas maneiras de abordar o problema. Ou atualize seu arquivo CSV antes de importar.