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

Localizar e substituir strings em documentos com eficiência


Certamente, se tudo o que você quer fazer é remover o   entidades do seu texto, basta fazer uma correspondência global e substituir:
db.tests.find({ "name": /\ /g }).forEach(function(doc) {
    doc.name = doc.name.replace(/ /g,"");
    db.tests.update({ "_id": doc._id },{ "$set": { "name": doc.name } });
});

Portanto, não deve haver necessidade de escrever todas as combinações, a regex substituirá muito correspondência com o /g opção. Possivelmente também use /m for multi-line é sua string "name" contém caracteres de nova linha. Veja um exemplo de regexer básico .

Também é recomendado usar $set para modificar apenas o(s) campo(s) que você realmente deseja ao invés de .save() todo o documento de volta. Há menos tráfego e menos chance de substituir as alterações que podem ter sido feitas por outro processo desde que o documento foi lido.

Idealmente, você usaria a API de operações em massa com o MongoDB versões 2.6 e superiores. Isso permite que as atualizações sejam "em lote" para que haja novamente menos tráfego entre o cliente e o servidor:
var bulk = db.tests.initializeOrderedBulkOp();
var count = 0;

db.tests.find({ "name": /\ /g }).forEach(function(doc) {
    doc.name = doc.name.replace(/ /g,"");
    bulk.find({ "_id": doc._id })
        .updateOne({ "$set": { "name": doc.name } });
    count++;

    if ( count % 1000 == 0 ) {
        bulk.execute();
        bulk = db.tests.initializeOrderedBulkOp();
    }
});

if  ( count % 1000 != 0 )
    bulk.execute();

Essas são suas principais maneiras de melhorar isso. Infelizmente, não há como uma instrução de atualização do MongoDB usar um valor existente como parte de sua expressão de atualização dessa maneira, portanto, a única maneira é fazer um loop, mas você pode fazer muito para reduzir as operações, conforme mostrado.