MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

Removendo espaços em branco (à esquerda e à direita) do valor da string


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.