MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

Effizientes Suchen und Ersetzen von Zeichenfolgen in Dokumenten

Sicherlich, wenn Sie nur den   entfernen möchten Entitäten aus Ihrem Text, dann führen Sie einfach eine globale Übereinstimmung durch und ersetzen:

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

Es sollte also nicht nötig sein, jede Kombination aufzuschreiben, die Regex ersetzt alle Übereinstimmungen durch /g Möglichkeit. Eventuell auch /m verwenden für mehrzeilig ist Ihre "Name"-Zeichenfolge enthält Zeilenumbruchzeichen. Sehen Sie sich ein einfaches Regexer-Beispiel an .

Es wird auch empfohlen, $set um nur die Felder zu ändern, die Sie wirklich wollen, anstatt .save() das ganze Dokument zurück. Es gibt weniger Verkehr und eine geringere Wahrscheinlichkeit, dass Änderungen überschrieben werden, die möglicherweise von einem anderen Prozess vorgenommen wurden, seit das Dokument gelesen wurde.

Idealerweise verwenden Sie die Bulk Operations API mit MongoDB-Versionen 2.6 und höher. Dadurch können die Aktualisierungen "gestapelt" werden, sodass es wieder weniger Datenverkehr zwischen dem Client und dem Server gibt:

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

Dies sind Ihre wichtigsten Möglichkeiten, dies zu verbessern. Leider gibt es für eine MongoDB-Update-Anweisung keine Möglichkeit, einen vorhandenen Wert auf diese Weise als Teil ihres Update-Ausdrucks zu verwenden, daher ist die einzige Möglichkeit eine Schleife, aber Sie können viel tun, um die Operationen wie gezeigt zu reduzieren.