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

Trova e sostituisci stringhe nei documenti in modo efficiente

Sicuramente se tutto ciò che vuoi fare è rimuovere il   entità dal tuo testo, quindi esegui semplicemente una corrispondenza globale e sostituisci:

db.tests.find({ "name": /\ /g }).forEach(function(doc) {
    doc.name = doc.name.replace(/ /g,"");
    db.tests.update({ "_id": doc._id },{ "$set": { "name": doc.name } });
});

Quindi non dovrebbe essere necessario scrivere ogni combinazione, la regex sostituirà molto match con il /g opzione. Eventualmente usa anche /m per multi-line è il tuo "nome" stringa contiene caratteri di nuova riga. Vedi un esempio di regexer di base .

Si consiglia inoltre di utilizzare $set per modificare solo i campi che vuoi veramente invece di .save() l'intero documento indietro. C'è meno traffico e meno possibilità di sovrascrivere le modifiche che potrebbero essere state apportate da un altro processo da quando il documento è stato letto.

Idealmente, dovresti utilizzare l'API Bulk Operations con MongoDB versioni 2.6 e successive. Ciò consente agli aggiornamenti di "batch" in modo che ci sia di nuovo meno traffico tra il client e il server:

var bulk = db.tests.initializeOrderedBulkOp();
var count = 0;

db.tests.find({ "name": /\ /g }).forEach(function(doc) {
    doc.name = doc.name.replace(/ /g,"");
    bulk.find({ "_id": doc._id })
        .updateOne({ "$set": { "name": doc.name } });
    count++;

    if ( count % 1000 == 0 ) {
        bulk.execute();
        bulk = db.tests.initializeOrderedBulkOp();
    }
});

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

Questi sono i tuoi modi principali per migliorare questo. Sfortunatamente non c'è modo per un'istruzione di aggiornamento MongoDB di utilizzare un valore esistente come parte della sua espressione di aggiornamento in questo modo, quindi l'unico modo è il ciclo, ma puoi fare molto per ridurre le operazioni come mostrato.