In einer Sammlung mit der folgenden allgemeinen Struktur:Zugreifen auf externe Parameter und Dokument in mongodb Gruppe Aggregation
{_id: 'id1', clientId: 'cid1', clientName:'Jon', item: 'item1', dateOfPurchase: '...'},
{_id: 'id2', clientId: 'cid1', clientName:'Jon', item: 'item2', dateOfPurchase: '...'},
{_id: 'id3', clientId: 'cid2', clientName:'Doe', item: 'itemX', dateOfPurchase: '...'}
... etc
Das Ziel ist, eine Gruppierung von clientId
zu erstellen einigen einfachen Statistiken zu berechnen, z.B. Gesamterscheinungen pro Client-ID.
Eine Möglichkeit, diese unter Verwendung von Node.js MongoDB Treiber-API Collection.group method zu erreichen ist:
db.collection.group(
'clientId',
{},
{ count: 0 },
function(obj, prev) {
prev.count++;
},
true
}
Der Ausgang dieses für die Abtastdaten oben würde ähnlich sein:
{clientId: 'cid1', count: 2}
{clientId: 'cid2', count: 1}
Frage 1 : Was ist der beste Weg, um einige externe Werte an die reducer
Funktion zu übergeben? Ich möchte zum Beispiel verschiedene Zählungen für Einkäufe vor/nach einem bestimmten Datum berechnen und dieses Datum als Parameter übergeben. Ich weiß, dass mit mapReduce
ich die scope
Option für diesen Zweck verwenden kann. Ich frage mich, ob es eine Möglichkeit gibt, dies mit der group
Funktion zu tun. Ich könnte das Iterator-Objekt verwenden, aber es fühlt sich hacky an.
Frage 2: Gibt es eine Möglichkeit, auf das Originaldokument innerhalb der finalize
-Funktion zuzugreifen, um einige zusätzliche Daten in die Ergebnisse einzubeziehen? dh Projekt zusätzliche Felder aus den Originaldokumenten wie clientName
:
{clientId: 'cid1', count: 2, clientName: 'Jon'}
{clientId: 'cid2', count: 1, clientName: 'Doe'}
Klärungen für Frage 2, a) ich das zusätzliche Feld innerhalb der reducer
Funktion hinzufügen könnte, aber es fühlt sich an redundanten Code enthalten, die angeblich nicht laufen bei jeder Iteration. b) ich Aggregat Pipelines verwenden könnte so etwas wie dies zu erreichen, aber ich frage mich, ob ich das mit Collection.group