MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

Mongodb - заявка за днешните общи суми, общите суми за седмицата и общите суми за месеца в една заявка

Това по-скоро е въпрос на това как очаквате да изглежда изходът, тъй като всеки обобщен резултат по същество трябва да се групира на най-ниското ниво и след това постепенно да се групира на по-високи „зърна“, докато се достигне най-голямото ниво („месец“). Този вид предполага данни, групирани по „месец“ в крайна сметка, освен ако не ги разделите по друг начин.

По същество, прогресивно $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" }
    }}
])

Така че всяко ниво след първото, което се сумира за ден, след това прогресивно се избутва в съдържанието на масива за неговата „закръглена“ стойност и общите суми след това се сумират и на това ниво.

Ако искате по-плосък изход с един запис на ден, съдържащ общите му седмични и месечни суми, както и общата сума за деня, тогава просто добавете две $unwind изрази до края на конвейера:

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

И по избор $project "пунктираните" полета се превръщат в нещо по-плоско и четливо, ако трябва.

Ако обхващате „години“ с това, тогава включете такава операция в ключа за групиране поне от ниво „седмица“, така че е възможно да не комбинирате данни от различни години и те да бъдат разделени.

Също така моето общо предпочитание е да използвам "date math" подход при закръгляване на дати, тъй като връща Date обект, но тъй като се използва на други нива освен "ден", можете просто да използвате алтернативно оператори за агрегиране на дати вместо това.

Няма нужда от mapReduce тъй като това е доста интуитивно и има ограничен брой дни в месеца, което означава, че ограничението на BSON при влагане на масиви в съдържанието по време на агрегиране няма да бъде нарушено.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. findAndModify или findOneAndUpdate - не е функция

  2. Сравнете дата (moment.js) в MongoDB

  3. Множество бази данни в MongoDB за SaaS

  4. Актуализиране на конкретен елемент в масив с MongoDB / Meteor

  5. Използвайте резултат от предишна заявка в друга заявка в mongodb