2010-11-10 9 views
37

Ich habe eine Sammlung mit 9 Millionen Datensätzen. Ich bin derzeit das folgende Skript die gesamte Sammlung zu aktualisieren:MongoDB - Was ist der schnellste Weg, um alle Datensätze in einer Sammlung zu aktualisieren?

simple_update.js

db.mydata.find().forEach(function(data) { 
    db.mydata.update({_id:data._id},{$set:{pid:(2571 - data.Y + (data.X * 2572))}}); 
}); 

Dies wird von der Kommandozeile ausgeführt werden, wie folgt:

mongo my_test simple_update.js 

Also alles, was ich bin doing ist ein neues Feld pid basierend auf einer einfachen Berechnung hinzufügen.

Gibt es einen schnelleren Weg? Dies kostet viel Zeit.

Antwort

27

Es gibt zwei Dinge, die Sie tun können.

  1. Senden Sie ein Update, wenn das Flag "multi" auf "true" gesetzt ist.
  2. Speichern Sie die Funktion serverseitig und versuchen Sie es mit server-side code execution.

Dieser Zusammenhang auch die folgenden Ratschläge enthält:

Dies ist eine gute Methode zur Durchführung von Batch-Verwaltungsarbeit. Führen Sie Mongo auf dem Server aus und verbinden Sie sich über die Localhost-Schnittstelle. Die Verbindung ist dann sehr schnell und mit geringer Latenz. Dies ist freundlicher als db.eval(), da db.eval() andere Operationen blockiert.

Dies ist wahrscheinlich der schnellste, den Sie bekommen werden. Sie müssen erkennen, dass die Ausgabe von 9M-Updates auf einem einzelnen Server eine schwere Operation sein wird. Nehmen wir an, Sie könnten 3k Updates/Sekunde bekommen, Sie sprechen immer noch davon, dass Sie fast eine Stunde lang laufen.

Und das ist nicht wirklich ein "Mongo-Problem", das wird eine Hardwarebeschränkung sein.

+0

würde mit mehreren Instanzen So (Slave/Master) es schneller machen? – mattjvincent

+0

Master/Slave wird Ihre Schreibzeit nicht verbessern. Mongo hat nur einen Schreib-Thread und ist normalerweise durch den Datendurchsatz begrenzt, wenn Sie ein solches Update durchführen. Die "mehrere Instanzen", die Sie benötigen, sind Sharding. Mit Sharding haben Sie zwei Maschinen mit zwei separaten Festplatten und Sie erhalten fast doppelt so viel Schreibdurchsatz. Schauen Sie sich aber wieder Ihre Hardware an und vergleichen Sie diese mit Ihrem erwarteten Durchsatz. –

+0

Ok. Ich verstehe das. Was ist mit Lesen? Gibt es eine Möglichkeit, das Lesen oder Abfragen zu beschleunigen? – mattjvincent

0

Nicht sicher, ob es schneller sein wird, aber Sie könnten ein Multi-Update durchführen. Sagen Sie einfach update where _id > 0 (dies gilt für jedes Objekt) und setzen Sie dann das Flag 'multi' auf 'true' und es sollte dasselbe geschehen, ohne dass Sie die gesamte Sammlung durchlaufen müssen.

Check this out: MongoDB - Server Side Code Execution

18

Ich bin mit den: db.collection.update method

// db.collection.update(criteria, objNew, upsert, multi) // --> for reference 
db.collection.update({ "_id" : { $exists : true } }, objNew, upsert, true); 
+6

Sie können auch {} (leeres BSSON-Objekt) für das erste Argument verwenden. Wenn Sie null verwenden, wird ein Fehler ausgegeben. Dies ist eine Inkonsistenz in der API, da andere Methoden null als Suchkriterien akzeptieren (und sie als "übereinstimmend" interpretieren), z. B. find- und findOne-Funktionen. –

Verwandte Themen