sql >> Database >  >> NoSQL >> MongoDB

Witruimten (vooraf en achteraan) verwijderen uit tekenreekswaarde

Het is momenteel niet mogelijk voor een update in MongoDB om te verwijzen naar de bestaande waarde van een huidig ​​veld bij het toepassen van de update. Dus je zult moeten herhalen:

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

Let op het gebruik van de $set operator daar en het geprojecteerde veld "categorie" alleen om het netwerkverkeer te verminderen"

Je zou kunnen beperken wat dat verwerkt met een $regex overeenkomen met:

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

Of zelfs als pure $regex zonder het gebruik van $and die je alleen nodig hebt in MongoDB waar meerdere voorwaarden op hetzelfde veld zouden worden toegepast. Anders $and is impliciet voor alle argumenten:

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

Wat de verwerking van overeenkomende documenten beperkt tot alleen documenten met voorloop- of volgspatie.

Als u zich zorgen maakt over het aantal documenten dat u moet zoeken, zou bulkupdates moeten helpen als u MongoDB 2.6 of hoger beschikbaar heeft:

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

Of zelfs met de API voor bulkbewerkingen voor MongoDB 2.6 en hoger:

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

Beste gedaan met bulkWrite() voor moderne API's die de Bulk Operations API gebruiken (technisch alles doet nu ) maar eigenlijk op een manier die veilig regressief . is met oudere versies van MongoDB. Hoewel dat in alle eerlijkheid zou betekenen vóór MongoDB 2.6 en dat u met een dergelijke versie ver buiten de dekking zou vallen voor officiële ondersteuningsopties. De codering is hiervoor wat schoner:

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

Die allemaal maar één keer operations naar de server sturen per 1000 documenten, of zoveel wijzigingen als u onder de 64 MB BSON-limiet past.

Als slechts een paar manieren om het probleem te benaderen. Of update eerst uw CSV-bestand voordat u het importeert.



  1. Failover voor MySQL-replicatie (en andere) - Moet dit worden geautomatiseerd?

  2. MongoDB op Ubuntu start niet als een service, niets in het logboek

  3. Hoe het originele document terug te krijgen na aggregatie

  4. waarom Redis single-threaded is (gebeurtenisgestuurd)