MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

Entfernen von Leerzeichen (führend und nachgestellt) aus dem Zeichenfolgenwert

Es ist derzeit nicht möglich, dass ein Update in MongoDB beim Anwenden des Updates auf den vorhandenen Wert eines aktuellen Felds verweist. Sie müssen also folgende Schleife ausführen:

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

Beachten Sie die Verwendung von $set Netzbetreiber dort und das geplante "Kategorie"-Feld nur, um den Netzwerkverkehr zu reduzieren"

Sie können die Verarbeitung mit einem $regex einschränken passend:

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

Oder sogar als reines $regex ohne die Verwendung von $and die Sie nur in MongoDB benötigen, wo mehrere Bedingungen auf dasselbe Feld angewendet würden. Andernfalls $and ist für alle Argumente implizit:

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

Dadurch werden die zu verarbeitenden abgeglichenen Dokumente auf diejenigen mit führenden oder nachgestellten Leerzeichen beschränkt.

Wenn Sie sich Sorgen über die Anzahl der zu durchsuchenden Dokumente machen, sollte die Massenaktualisierung hilfreich sein, wenn Sie über MongoDB 2.6 oder höher verfügen:

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

Oder sogar mit der Massenoperations-API für MongoDB 2.6 und höher:

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

Am besten erfolgt mit bulkWrite() für moderne APIs, die die Bulk Operations API verwenden (technisch gesehen alles tut jetzt ), aber tatsächlich auf eine Weise, die sicher regressiv ist mit älteren Versionen von MongoDB. Ehrlich gesagt würde dies jedoch bedeuten, dass Sie vor MongoDB 2.6 keine offiziellen Supportoptionen mit einer solchen Version erhalten. Dafür ist die Codierung etwas sauberer:

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 alle Operationen nur einmal an den Server senden pro 1000 Dokumente oder so viele Änderungen, wie Sie unter die 64-MB-BSON-Grenze passen können.

Als nur einige Möglichkeiten, das Problem anzugehen. Oder aktualisieren Sie zuerst Ihre CSV-Datei, bevor Sie sie importieren.