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

MongoDB:Como renomear um campo usando regex


Esta não é uma operação mapReduce, a menos que você queira uma nova coleção que consiste apenas no _id e valor campos que são produzidos a partir da saída mapReduce, assim como:
    "_id": ObjectId("53f2b954b55e91756c81d3a5"), 
    "value": { 
        "domain": "example.com",
        ... 
    } 
}

Que na melhor das hipóteses é uma espécie de retrabalho "do lado do servidor" de sua coleção, mas é claro que não na estrutura que você deseja.

Embora existam maneiras de executar todo o código no servidor, não tente fazê-lo, a menos que esteja realmente em apuros. Essas maneiras geralmente não funcionam bem com o sharding, que geralmente é onde as pessoas "realmente estão em um local" pelo tamanho dos registros.

Quando você deseja alterar as coisas e fazê-lo em massa, geralmente é necessário "fazer um loop" nos resultados da coleta e processar as atualizações enquanto tem acesso às informações do documento atual. Ou seja, no caso de sua "atualização" ser "baseada em" informações já contidas em campos ou estrutura do documento.

Portanto, não há operação de "substituição de regex" disponível e certamente não há uma para renomear um campo. Então, vamos fazer um loop com as operações em massa para a forma "mais segura" de fazer isso sem executar o código todo no servidor.
var bulk = db.collection.initializeOrderedBulkOp();
var counter = 0;

db.collection.find().forEach(function(doc) {

    for ( var k in doc ) {
        if ( doc[k].match(/^2014.*/) ) {
            var update = {};
            update["$unset"][k] = 1;
            update["$set"][ k.replace(/(\d+)-(\d+)-(\d+).+/,"$1$2$3") ] = doc[k];
            bulk.find({ "_id": doc._id }).updateOne(update);
            counter++;
        }
    }

    if ( counter % 1000 == 0 ) {
        bulk.execute();
        bulk = db.collection.initializeOrderedBulkOp();
    }

});

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

Portanto, as principais coisas são o $unset operador para remover o campo existente e o $set operador para criar o novo campo no documento. Você precisa que o conteúdo do documento examine e use o "nome do campo" e o "valor", portanto, o loop, pois não há outra maneira.

Se você não tiver o MongoDB 2.6 ou superior no servidor, o conceito de loop ainda permanecerá sem o benefício imediato de desempenho. Você pode pesquisar coisas como .eval() para processar no servidor, mas como a documentação sugere, realmente não é recomendado. Use com cuidado se for necessário.