MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Suppression des espaces blancs (de début et de fin) de la valeur de chaîne

Il n'est actuellement pas possible pour une mise à jour dans MongoDB de faire référence à la valeur existante d'un champ actuel lors de l'application de la mise à jour. Il va donc falloir boucler :

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

Notant l'utilisation du $set opérateur là-bas et le champ "catégorie" projeté uniquement afin de réduire le trafic réseau"

Vous pouvez limiter ce qui est traité avec un $regex pour correspondre :

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

Ou même en tant que pure $regex sans l'utilisation de $and dont vous n'avez besoin que dans MongoDB où plusieurs conditions seraient appliquées au même champ. Sinon $and est implicite à tous les arguments :

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

Ce qui limite les documents correspondants à traiter uniquement à ceux avec un espace blanc au début ou à la fin.

Si vous vous inquiétez du nombre de documents à consulter, la mise à jour groupée devrait vous aider si vous disposez de MongoDB 2.6 ou d'une version ultérieure :

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

Ou même avec l'API d'opérations en bloc pour MongoDB 2.6 et supérieur :

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

Meilleur fait avec bulkWrite() pour les API modernes qui utilisent l'API Bulk Operations (techniquement tout fait maintenant ) mais en fait d'une manière qui est régressive en toute sécurité avec les anciennes versions de MongoDB. Bien qu'en toute honnêteté, cela signifierait avant MongoDB 2.6 et vous seriez bien hors de couverture pour les options de support officielles utilisant une telle version. Le codage est un peu plus propre pour cela :

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

Qui n'envoient tous les opérations au serveur qu'une fois pour 1 000 documents, ou autant de modifications que possible dans la limite de 64 Mo BSON.

Comme quelques façons d'aborder le problème. Ou mettez à jour votre fichier CSV avant de l'importer.