sql >> Database teknologi >  >> NoSQL >> MongoDB

MongoDB:Sådan omdøbes et felt ved hjælp af regex

Dette er ikke en mapReduce-operation, ikke medmindre du ønsker en ny samling, der kun består af _id og værdi felter, der er produceret fra mapReduce output, ligesom:

    "_id": ObjectId("53f2b954b55e91756c81d3a5"), 
    "value": { 
        "domain": "example.com",
        ... 
    } 
}

Hvilket i bedste fald er en slags "serverside"-bearbejdning af din samling, men selvfølgelig ikke i den struktur, du ønsker.

Selvom der er måder at udføre al koden på serveren på, så prøv ikke at gøre det, medmindre du virkelig er på et sted. Disse måder spiller generelt ikke godt med sharding alligevel, hvilket normalt er der, hvor folk "virkelig er på plads" for den store størrelse af rekorder.

Når du vil ændre ting og gøre det i bulk, skal du generelt "loope" indsamlingsresultaterne og behandle opdateringerne, mens du har adgang til de aktuelle dokumentoplysninger. Det vil sige i det tilfælde, hvor din "opdatering" er "baseret på" oplysninger, der allerede er indeholdt i felter eller strukturen af ​​dokumentet.

Der er derfor ikke en "regex replace"-operation tilgængelig, og der er bestemt ikke en til at omdøbe et felt. Så lad os gå i løkke med bulk operationer for den "sikreste" form for at gøre dette uden at køre koden alt sammen på serveren.

var bulk = db.collection.initializeOrderedBulkOp();
var counter = 0;

db.collection.find().forEach(function(doc) {

    for ( var k in doc ) {
        if ( doc[k].match(/^2014.*/) ) {
            var update = {};
            update["$unset"][k] = 1;
            update["$set"][ k.replace(/(\d+)-(\d+)-(\d+).+/,"$1$2$3") ] = doc[k];
            bulk.find({ "_id": doc._id }).updateOne(update);
            counter++;
        }
    }

    if ( counter % 1000 == 0 ) {
        bulk.execute();
        bulk = db.collection.initializeOrderedBulkOp();
    }

});

if ( counter % 1000 != 0 )
    bulk.execute();

Så de vigtigste ting er $unset operatør for at fjerne det eksisterende felt og $set operatør for at oprette det nye felt i dokumentet. Du har brug for dokumentindholdet til at undersøge og bruge både "feltnavnet" og "værdien", så deraf loopingen, da der ikke er nogen anden måde.

Hvis du ikke har MongoDB 2.6 eller nyere på serveren, forbliver looping-konceptet stadig uden den umiddelbare ydeevnefordel. Du kan se nærmere på ting som .eval() for at kunne behandle på serveren, men som dokumentationen antyder, anbefales det virkelig ikke. Brug med forsigtighed, hvis du skal.



  1. NoSQL Trends – MongoDB, Cassandra, CouchDB &Riak

  2. Dvalemodulfejl OGM + MongoDB og Wildfly 10

  3. Hvorfor får Mongo-hint en forespørgsel til at køre op til 10 gange hurtigere?

  4. Find og erstat strenge i dokumenter effektivt