MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

Aggregierte $group für mehrere Datumsbereiche

Sie müssen den Gruppierungsschlüssel bedingt bestimmen, basierend darauf, wo das aktuelle Datum in den Bereich fällt. Dies wird im Wesentlichen über $cond erreicht mit verschachtelten Bedingungen und der logischen Variante von $lt :

// work out dates somehow
var today = new Date(),
    oneDay = ( 1000 * 60 * 60 * 24 ),
    thirtyDays = new Date( today.valueOf() - ( 30 * oneDay ) ),
    fifteenDays = new Date( today.valueOf() - ( 15 * oneDay ) ),
    sevenDays = new Date( today.valueOf() - ( 7 * oneDay ) );

db.collection.aggregate([
    { "$match": {
        "date": { "$gte": thirtyDays }
    }},
    { "$group": {
        "_id": {
            "$cond": [
                { "$lt": [ "$date", fifteenDays ] },
                "16-30",
                { "$cond": [
                    { "$lt": [ "$date", sevenDays ] },
                    "08-15",
                    "01-07"
                ]}
            ]
        },
        "count": { "$sum": 1 },
        "totalValue": { "$sum": "$value" }
    }}
])

Als $cond ein ternärer Operator ist, wird die erste Bedingung ausgewertet, um zu sehen, ob die Bedingung wahr ist, und wenn sie wahr ist, wird das zweite Argument zurückgegeben, andernfalls wird das dritte zurückgegeben, wenn sie falsch ist. Also durch Verschachteln eines weiteren $cond Im falschen Fall erhalten Sie den logischen Test, wo das Datum liegt, entweder "weniger als das 15-Tage-Datum", was bedeutet, dass es im ältesten Bereich liegt, oder "weniger als 7 Tage", was im mittleren Bereich bedeutet, oder natürlich ist es in das neueste Sortiment.

Ich stelle hier nur den Zahlen kleiner als 10 eine 0 voran Sie haben also etwas zum Sortieren, wenn Sie möchten, seit der Ausgabe von "keys" in $group ist an sich nicht bestellt.

Aber so machen Sie das in einer einzigen Abfrage. Sie berechnen einfach, was der Gruppierungsschlüssel sein sollte, basierend darauf, wo das Datum liegt, und akkumulieren für jeden Schlüssel.