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

Encuentre y reemplace cadenas en documentos de manera eficiente

Seguramente si todo lo que quieres hacer es quitar el   entidades de su texto, simplemente haga una coincidencia global y reemplace:

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

Por lo tanto, no debería haber necesidad de escribir cada combinación, la expresión regular reemplazará la coincidencia con /g opción. Posiblemente también use /m para varias líneas es su cadena de "nombre" contiene caracteres de nueva línea. Vea un ejemplo de regexer básico. .

También se recomienda usar $set para modificar solo los campos que realmente desea en lugar de .save() todo el documento de vuelta. Hay menos tráfico y menos posibilidades de sobrescribir los cambios que podría haber realizado otro proceso desde que se leyó el documento.

Idealmente, usaría la API de operaciones masivas con las versiones 2.6 y posteriores de MongoDB. Esto permite que las actualizaciones sean "por lotes", por lo que nuevamente hay menos tráfico entre el cliente y el 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();

Esas son sus principales formas de mejorar esto. Desafortunadamente, no hay forma de que una declaración de actualización de MongoDB use un valor existente como parte de su expresión de actualización de esta manera, por lo que la única forma es en bucle, pero puede hacer mucho para reducir las operaciones como se muestra.