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

MongoDB:come rinominare un campo usando regex

Questa non è un'operazione mapReduce, a meno che tu non voglia una nuova collezione composta solo da _id e value campi prodotti dall'output di mapReduce, proprio come:

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

Che nella migliore delle ipotesi è una sorta di rielaborazione "lato server" della tua collezione, ma ovviamente non nella struttura che desideri.

Sebbene ci siano modi per eseguire tutto il codice nel server, per favore non provare a farlo a meno che tu non sia davvero in una posizione. Questi metodi generalmente non funzionano bene con lo sharding, che di solito è il punto in cui le persone "sono davvero in una posizione" per l'enorme dimensione dei record.

Quando si desidera modificare le cose e farlo in blocco, in genere è necessario eseguire il "loop" dei risultati della raccolta ed elaborare gli aggiornamenti pur avendo accesso alle informazioni sul documento corrente. Cioè, nel caso in cui il tuo "aggiornamento" sia "basato su" informazioni già contenute nei campi o nella struttura del documento.

Non è quindi disponibile un'operazione di "sostituzione regex" e certamente non ce n'è una per rinominare un campo. Quindi continuiamo con le operazioni collettive per la forma "più sicura" di farlo senza eseguire il codice tutto sul server.

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

Quindi le cose principali sono $unset operatore per rimuovere il campo esistente e il $set operatore per creare il nuovo campo nel documento. È necessario che il contenuto del documento esamini e utilizzi sia il "nome campo" che il "valore", quindi il looping in quanto non c'è altro modo.

Se non hai MongoDB 2.6 o versioni successive sul server, il concetto di loop rimane comunque senza il vantaggio immediato delle prestazioni. Puoi esaminare cose come .eval() per elaborare sul server, ma come suggerisce la documentazione, non è davvero raccomandato. Usalo con cautela, se necessario.