sql >> Base de Datos >  >> NoSQL >> MongoDB

MongoDB:cómo cambiar el nombre de un campo usando expresiones regulares

Esta no es una operación mapReduce, a menos que desee una nueva colección que consista solo en _id y value campos que se producen a partir de la salida de mapReduce, como:

    "_id": ObjectId("53f2b954b55e91756c81d3a5"), 
    "value": { 
        "domain": "example.com",
        ... 
    } 
}

Lo que en el mejor de los casos es una especie de reelaboración del "lado del servidor" de su colección, pero por supuesto no en la estructura que desea.

Si bien hay formas de ejecutar todo el código en el servidor, no intente hacerlo a menos que realmente esté en un lugar. De todos modos, estas formas generalmente no funcionan bien con la fragmentación, que generalmente es donde las personas "realmente están en un lugar" por el gran tamaño de los registros.

Cuando desea cambiar cosas y hacerlo de forma masiva, generalmente tiene que "repetir" los resultados de la recopilación y procesar las actualizaciones mientras tiene acceso a la información del documento actual. Es decir, en el caso de que su "actualización" esté "basada en" información ya contenida en campos o estructura del documento.

Por lo tanto, no hay una operación de "reemplazo de expresiones regulares" disponible, y ciertamente no hay una para cambiar el nombre de un campo. Así que hagamos un bucle con operaciones masivas para la forma "más segura" de hacer esto sin ejecutar todo el código en el 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();

Entonces, las cosas principales son $unset operador para eliminar el campo existente y el $set operador para crear el nuevo campo en el documento. Necesita el contenido del documento para examinar y usar tanto el "nombre de campo" como el "valor", por lo tanto, el bucle ya que no hay otra forma.

Si no tiene MongoDB 2.6 o superior en el servidor, el concepto de bucle aún permanece sin el beneficio de rendimiento inmediato. Puede buscar cosas como .eval() para procesar en el servidor, pero como sugiere la documentación, realmente no se recomienda. Úselo con precaución si es necesario.