MongoDB
 sql >> Baza danych >  >> NoSQL >> MongoDB

Mongodb — zapytaj w jednym zapytaniu o sumy z dnia dzisiejszego, sumy z tygodnia i sumy z miesiąca

Jest to raczej kwestia tego, jak oczekujesz wyniku, ponieważ każdy zagregowany wynik zasadniczo musi być grupowany na najniższym poziomie, a następnie stopniowo grupowany na wyższych „ziarnach” aż do osiągnięcia najwyższego poziomu („miesiąc”). Ten rodzaj oznacza dane pogrupowane według „miesiąca”, chyba że podzielisz je w inny sposób.

Zasadniczo stopniowo $group :

db.collection.aggregate([
    // First total per day. Rounding dates with math here
    { "$group": {
        "_id": {
            "$add": [
                { "$subtract": [
                    { "$subtract": [ "$createdAt", new Date(0) ] },
                    { "$mod": [
                        { "$subtract": [ "$createdAt", new Date(0) ] },
                        1000 * 60 * 60 * 24
                    ]}                        
                ]},
                new Date(0)
            ]
        },
        "week": { "$first": { "$week": "$createdAt" } },
        "month": { "$first": { "$month": "$createdAt" } },
        "total": { "$sum": "$num" }
    }},

    // Then group by week
    { "$group": {
        "_id": "$week",
        "month": { "$first": "$month" },
        "days": {
            "$push": {
                "day": "$_id",
                "total": "$total"
            }
        },
        "total": { "$sum": "$total" }
    }},

    // Then group by month
    { "$group": {
        "_id": "$month",
        "weeks": {
            "$push": {
                "week": "$_id",
                "total": "$total",
                "days": "$days"
            }
        },
        "total": { "$sum": "$total" }
    }}
])

Tak więc każdy poziom po pierwszym, który sumuje się na dzień, jest stopniowo umieszczany w zawartości tablicy ze względu na swoją wartość „zaokrągloną w górę”, a sumy są następnie sumowane również na tym poziomie.

Jeśli chcesz uzyskać bardziej płaskie dane wyjściowe z jednym rekordem dziennie zawierającym sumy tygodniowe i miesięczne, a także sumę dniową, po prostu dołącz dwa $unwind oświadczenia do końca potoku:

{ "$unwind": "$weeks" },
{ "$unwind": "$weeks.days" }

I opcjonalnie $project "kropkowane" pola są bardziej płaskie i czytelne, jeśli musisz.

Jeśli obejmujesz tym "lata", uwzględnij taką operację w kluczu grupującym przynajmniej z poziomu "tydzień", aby nie łączyć danych z różnych lat i są one rozdzielone.

Preferuję również używanie "matematyka dat" podejście podczas zaokrąglania dat, ponieważ zwraca Date obiekt, ale tak jak jest używany na innych poziomach niż „dzień”, możesz po prostu naprzemiennie użyć operatory agregacji dat zamiast tego.

Nie ma potrzeby stosowania mapReduce ponieważ jest to dość intuicyjne i istnieje skończona liczba dni w miesiącu, co oznacza, że ​​limit BSON podczas zagnieżdżania tablic w treści podczas agregacji nie zostanie złamany.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Drukowanie wyników zapytania z Mongodb w Scali za pomocą mongo-scala-driver

  2. Kompas MongoDB - utknął podczas łączenia się z Atlasem

  3. Optymalizacja środowiska Linux pod kątem MongoDB

  4. Agregacja w lokalnej strefie czasowej w mongodb

  5. Dlaczego otrzymuję wyjątek java.lang.IllegalArgumentException dla sterownika Casbah / Java MongoDB?