MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Rechercher et remplacer efficacement des chaînes dans des documents

Sûrement si tout ce que vous voulez faire est de supprimer le   entités de votre texte, faites simplement une correspondance globale et remplacez :

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

Il ne devrait donc pas être nécessaire d'écrire chaque combinaison, la regex remplacera very match par le /g option. Utilisez éventuellement /m pour plusieurs lignes, votre chaîne "nom" contient des caractères de nouvelle ligne. Voir un exemple de base regexer .

Il est également recommandé d'utiliser $set afin de ne modifier que le(s) champ(s) que vous voulez vraiment plutôt que .save() l'ensemble du document. Il y a moins de trafic et moins de risques d'écraser les modifications qui auraient pu être apportées par un autre processus depuis la lecture du document.

Idéalement, vous utiliseriez l'API Bulk Operations avec les versions 2.6 et supérieures de MongoDB. Cela permet aux mises à jour d'être "par lots" afin qu'il y ait à nouveau moins de trafic entre le client et le serveur :

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

Ce sont vos principaux moyens d'améliorer cela. Malheureusement, il n'y a aucun moyen pour une instruction de mise à jour MongoDB d'utiliser une valeur existante dans le cadre de son expression de mise à jour de cette manière, donc le seul moyen est de boucler, mais vous pouvez faire beaucoup pour réduire les opérations comme indiqué.