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

Eliminación de espacios en blanco (al principio y al final) del valor de la cadena

Actualmente no es posible que una actualización en MongoDB se refiera al valor existente de un campo actual al aplicar la actualización. Así que vas a tener que hacer un bucle:

db.collection.find({},{ "category": 1 }).forEach(function(doc) {
   doc.category = doc.category.trim();
   db.collection.update(
       { "_id": doc._id },
       { "$set": { "category": doc.category } }
   );
})

Tomando nota del uso de $set operador allí y el campo de "categoría" proyectado solo para reducir el tráfico de red"

Puede limitar lo que procesa con un $regex para hacer coincidir:

db.collection.find({ 
    "$and": [
        { "category": /^\s+/ },
        { "category": /\s+$/ }
    ]
})

O incluso como puro $regex sin el uso de $and que solo necesita en MongoDB donde se aplicarían múltiples condiciones al mismo campo. De lo contrario $and está implícito en todos los argumentos:

db.collection.find({ "category": /^\s+|\s+$/ })

Lo que restringe el procesamiento de los documentos coincidentes a solo aquellos con espacios en blanco al principio o al final.

Si le preocupa la cantidad de documentos que debe buscar, la actualización masiva debería ayudar si tiene MongoDB 2.6 o superior disponible:

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);

O incluso con la API de operaciones masivas para MongoDB 2.6 y 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();

Mejor hecho con bulkWrite() para las API modernas que utilizan la API de operaciones masivas (técnicamente todo hace ahora) pero en realidad de una manera que es seguramente regresiva con versiones anteriores de MongoDB. Aunque, con toda honestidad, eso significaría antes de MongoDB 2.6 y estaría fuera de la cobertura de las opciones de soporte oficial que utilizan dicha versión. La codificación es algo más limpia para esto:

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 = [];
}

Que solo envían operaciones al servidor una vez por 1000 documentos, o tantas modificaciones como pueda por debajo del límite de BSON de 64 MB.

Como solo algunas formas de abordar el problema. O actualice su archivo CSV antes de importar.