Ich startete MongoDB Server mit ausführlichen Flagge. Das habe ich bekommen.
Option 1. update_all auf einem Selektor angewendet
2017-04-25 COMMAND command production_v3.$cmd command: update { update: "products", updates: [ { q: { ... }, u: { $addToSet: { test_field: "value_to_add" } }, multi: true, upsert: false } ], ordered: true }
I eine Ausgabe entfernt, so dass leichter zu lesen ist. Der Ablauf ist:
- MongoID generiert einen einzelnen Befehl mit Abfrage und Update angegeben.
- MongoDB-Server erhält den Befehl. Es geht durch Sammlung und aktualisiert jedes Match in [vage] one go.
Hinweis! Sie können aus dem Quellcode lernen oder als gegeben annehmen. Da MongoID gemäß meiner Terminologie den Befehl zum Senden in Schritt 1 generiert, werden Ihre Modelle nicht überprüft. z.B. Wenn 'some.field.value' nicht zu Ihrem Feld im Modellbenutzer gehört, wird der Befehl weiterhin ausgeführt und verbleibt in der Datenbank.
Option 2. jeweils an einem Wähler
ich Befehle erhalten finden wie unten gefolgt von mehreren GETMORE-s:
2017-04-25 COMMAND command production_v3.products command: find { find: "products", filter: { ... } } 0ms
ich auch eine große Anzahl von update-s erhalten:
2017-04-25 COMMAND command production_v3.$cmd command: update { update: "products", updates: [ { q: { _id: ObjectId('52a6db196c3f4f422500f255') }, u: { $addToSet: { test_field: { $each: [ "value_to_add" ] } } }, multi: false, upsert: false } ], ordered: true } 0ms
Der Durchfluss unterscheidet sich radikal von der ersten Option:
- MongoID sendet eine einfache Abfrage an den MongoDB-Server. Wenn Ihre Auflistung groß genug ist und die Abfrage einen wesentlichen Teil davon abdeckt, passiert Folgendes in einer Schleife:
- [Schleife] Reagieren Sie mit einer Teilmenge aller Übereinstimmungen. Lassen Sie den Rest für die nächste Iteration.
- [loop] MongoID erhält ein Array von passenden Elementen im Hash-Format. MongoID analysiert jeden Eintrag und initialisiert die Benutzerklasse dafür. Das ist eine teure Operation!
- [loop] MongoID generiert für jede Benutzerinstanz aus dem vorherigen Schritt ein Aktualisierungskommando und sendet es an serve. Steckdosen sind auch teuer.
- [Schleife] MongoDB erhält den Befehl und durchläuft die Sammlung bis zum ersten Treffer. Aktualisiert das Spiel. Es ist schnell, addiert sich aber einmal in einer Schleife.
- [Schleife] MongoID analysiert die Antwort und aktualisiert ihre Benutzerinstanz entsprechend. Teuer und unnötig.
Option 3. add_to_set auf einem Selektor angewandt
Unter der Haube ist es gleichbedeutend mit Option 1. Die CPU und Speicher-Overhead für das Wohl der Frage unerheblich ist.
Fazit.
Option 2 ist so viel langsamer, dass Benchmarking keinen Sinn macht. In dem speziellen Fall, den ich versuche, führte dies zu einer 1000-prozentigen Anfrage an MongoDB und einer 1000er User Class-Initialisierung. Die Optionen 1 und 3 führten zu einer einzigen Anfrage an MongoDB und beruhten auf der hochoptimierten Engine von MongoDB.