Wir müssen die Datensatzanzahl für Datensätze in einer Accounts-Auflistung basierend auf einem "type" -Feld verfolgen. Wir wollen also wissen, wie viele Konten in TYPE1 sind, wie viele in TYPE2 sind usw. Außerdem müssen wir die Gesamtsummen eines Betragsfelds in jedem Konto kennen.
Aggregierte Abfragen sind für uns nicht schnell genug (diese Anzahl muss in Echtzeit in der Benutzeroberfläche aktualisiert werden und wir werden 10 Millionen Datensätze haben, Aggregatabfragen, die viele Sekunden dauern, werden nicht ausgeführt um es zu schneiden), also schaue ich auf eine separate Summensammlung mit einem Objekt, das Zähler für jeden Typ verfolgt.
Wenn wir den Wert des 'type'-Feldes ändern (dh das Konto von einem Typ in einen anderen verschieben), müssen wir die Zählungen und' Wert'-Summen anpassen (den Zähler für den ursprünglichen Typ dekrementieren, den Zähler für der neue Typ). Wir können dann einen Aktualisierungsbefehl mit $ incr () verwenden, um die Felder im Summensatz anzupassen, der die Typenzählungen und Wertesummen speichert. (Dies bedeutet, dass wir für jedes "Typ" -Update zwei Datenbankschreibvorgänge haben, aber ich sehe keinen Weg, bis jemand einen Vorschlag hat).
Für einzelne Datensatzanpassungen ist das ziemlich einfach - wir können einfach die Typänderung in unserer Datenzugriffsebene auffangen und eine sekundäre Aktualisierung im Summenverfolgungsobjekt vornehmen.
Das Problem besteht darin, wie Sie die Summe der Beträge nachverfolgen können. Für einzelne Aufnahmeeinstellungen ist dies kein Problem. Aber für Massenoperationen (db.collection.update (), die viele tausend Datensätze beeinflussen könnten), müssen wir die Summe des Felds 'Betrag' für jeden angepassten Datensatz ermitteln.
Bisher war ich nicht in der Lage, einen Weg zu finden, Mongo dazu zu bringen, die Informationen zu bekommen, die ich brauche.
Ich habe eine Strategie ausgearbeitet, die das Hinzufügen eines markierten Historienarrays im Account-Objekt mit einer eindeutigen "changeId" und dem "Betrag" des Dokumentdatensatzes zum Zeitpunkt der Änderung beinhaltet, und dann ein Aggregat dagegen laufen lassen history record für die changeId, um die Summen zu erhalten. Löschen Sie optional den Verlaufsdatensatz (oder führen Sie dies in einem periodischen Bereinigungsprozess durch).
Wenn ich zum Beispiel eine Massenänderung vorgenommen habe, würde ich eine eindeutige ID ('aaaaaaaa' im folgenden) generieren und dann eine Array-Einfügung für einen Verlaufsdatensatz als Teil der Massenaktualisierung durchführen, die den 'Typ' anpasst. :
%Vor%Dann kann ich ein Aggregat erstellen, das mir die Summe der 'Menge' für die gerade ausgeführte Änderungs-ID gibt.
Ich denke, das wird funktionieren, aber es ist ungeschickt - gibt es einen besseren Weg?
Mein erster Instinkt besteht darin, ein Änderungsprotokoll in einer separaten Sammlung zu speichern, aber ich sehe keinen Weg, dies in der MongoDB-Sammlungsdokumentation zu tun. Ich stimme zu, dass die Wartung der Aggregate in einem separaten Prozess erfolgen muss. Ihre Idee, ein historisches Array in der Account-Sammlung zu erstellen, kann funktionieren. Ich kenne Ihre Anwendung nicht, aber ich würde die Struktur leicht ändern, um ein Timing-Loch zu vermeiden. Ich würde ein Ticker-Band von Änderungen erstellen, die der aggregierte Prozess mit wenig Kenntnis des Kontos anwenden kann.
%Vor%Der Grund liegt am Timing des Sammelvorgangs. Wenn Sie Ihre ursprüngliche Struktur verwenden, muss sie den neuen Betrag vom Konto selbst erhalten. Was passiert aber, wenn sich das Konto erneut ändert, bevor der Sammlungsvorgang ausgeführt wird? Sagen wir, die Transaktionen sind wie folgt:
%Vor%Wenn Sie die folgende Struktur verwenden, muss Ihr Aggregationsprozess die Änderung des Typs 2 ignorieren, da er sich selbst aufhebt.
%Vor%Ich würde Folgendes tun. Der aggregierte Prozess wird alle Typ1-Datensätze im Verlauf finden und das Aggregat ausführen. Also für Type1, wird es 1 und -1 für keinen Unterschied in der Anzahl und -2000 und 1000, um den Typ1 Betrag um 1000 zu dekrementieren. Das Type2-Aggregat wird aufgehoben.
%Vor%Unabhängig davon, was Sie tun möchten, müssen Sie ermitteln, welche Verlaufsdatensätze bereits verarbeitet wurden. Sie können die Verlaufsdokumente nach der Verarbeitung entweder löschen, kennzeichnen oder in eine Prüfsammlung verschieben.
Tags und Links mongodb