sql >> Databasteknik >  >> NoSQL >> MongoDB

Ta bort blanksteg (ledande och efterföljande) från strängvärde

Det är för närvarande inte möjligt för en uppdatering i MongoDB att referera till det befintliga värdet för ett aktuellt fält när uppdateringen tillämpas. Så du kommer att behöva loopa:

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

Notera användningen av $set operatör där och det projicerade fältet "kategori" endast för att minska nätverkstrafiken"

Du kan begränsa vad som bearbetas med en $regex att matcha:

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

Eller till och med som ren $regex utan användning av $and som du bara behöver i MongoDB där flera villkor skulle tillämpas på samma fält. Annars $and är implicit för alla argument:

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

Vilket begränsar de matchade dokumenten att behandla till endast de med inledande eller efterföljande blanksteg.

Om du är orolig för antalet dokument att titta på, bör massuppdatering hjälpa dig om du har MongoDB 2.6 eller senare tillgänglig:

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

Eller till och med med bulk operations API för MongoDB 2.6 och högre:

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

Bäst gjort med bulkWrite() för moderna API:er som använder Bulk Operations API (tekniskt sett allt). gör nu ) men faktiskt på ett sätt som är säkert regressivt med äldre versioner av MongoDB. Fast i ärlighetens namn skulle det betyda före MongoDB 2.6 och att du skulle vara långt utanför täckning för officiella supportalternativ med en sådan version. Kodningen är något renare för detta:

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

Som alla bara skickar operationer till servern en gång per 1000 dokument, eller så många ändringar du kan få plats under 64 MB BSON-gränsen.

Som bara några sätt att närma sig problemet. Eller uppdatera din CSV-fil innan du importerar.



  1. Redis auth-fel med Node.js och socket.io

  2. Returnera det sista sanna värdet för varje grupp

  3. Kombinera fulltext med annat index

  4. Redis på Azure Performance Benchmark – ScaleGrid för Redis™ kontra Azure Cache