Nehmen wir an, ich habe eine Sammlung mit Dokumenten, die so aussehen (nur vereinfachtes Beispiel, aber es sollte das Schema zeigen):
%Vor%Jetzt muss ich einige Statistiken über diese Sammlung sammeln. Zum Beispiel:
%Vor%sammelt die Gesamtsummen in der 'stat'-Sammlung.
%Vor%An diesem Punkt ist alles perfekt, aber ich habe den nächsten Schritt gemacht:
Die Frage ist also:
Gibt es eine Möglichkeit, nur Dokumente auszuwählen, die nach dem letzten mapReduce hinzugefügt wurden, um inkrementelles mapReduce auszuführen, oder gibt es eine andere Strategie, um statistische Daten über eine ständig wachsende Sammlung zu aktualisieren?
Sie können die Zeit zwischenspeichern und als Barriere für Ihre nächste inkrementelle Kartenreduzierung verwenden.
Wir testen das bei der Arbeit und es scheint zu funktionieren. Korrigiere mich, wenn ich falsch liege, aber du kannst nicht sicher Map-Reducing durchführen, während ein Insert über Shards hinweg passiert. Die Versionen werden inkonsistent und Ihre Map-Reduce-Operation schlägt fehl. (Wenn Sie eine Lösung dafür finden, lassen Sie es mich wissen!)
Wir verwenden stattdessen alle 5 Minuten Bulk-Inserts. Sobald alle Bulk-Inserts fertig sind, führen wir das Map-Reduce wie folgt aus (in Python):
%Vor% Beachten Sie, dass wir reduce
und nicht merge
verwendet haben, weil wir nicht das überschreiben wollen, was wir vorher hatten; Wir wollen die alten Ergebnisse und das neue Ergebnis mit derselben Reduzierungsfunktion kombinieren.
Sie können mit _id.getTime()
(aus: ) nur den Zeitanteil der ID ermitteln Ссылка ). Das sollte über alle Shards sortierbar sein.
EDIT: Entschuldigung, das war die Java-Dokumentation ... Die JS-Version scheint _id.generation_time.in_time_zone (Time.zone) zu sein, von Ссылка
Ich habe eine vollständige Pymongo-basierte Lösung geschrieben, die inkrementelle Map-Reduce-Methoden verwendet, die Zeit zwischenspeichert und erwartet, dass sie in einem Cron-Job ausgeführt wird. Es sperrt sich selbst, so dass zwei nicht gleichzeitig ausgeführt werden können:
%Vor%Wir lösen dieses Problem mit 'normalisierten' ObjectIds. Schritte, die wir machen:
new ObjectId(objectId.Timestamp,
0, short.MinValue, 0)
Hinweis: Einige Randelemente werden mehrmals verarbeitet. Um es zu beheben, setzen wir eine Art Flag in den verarbeiteten Elementen.