sql >> Database >  >> NoSQL >> MongoDB

Groeperen op datumintervallen

Er zijn datumaggregatie-operators beschikbaar voor het aggregatieraamwerk van MongoDB. Dus bijvoorbeeld een $dayOfYear operator wordt gebruikt om die waarde te krijgen vanaf de datum voor gebruik in groepering:

db.collection.aggregate([
    { "$group": {
        "_id": { "$dayOfYear": "$datetime" },
        "total": { "$sum": "$count" }
    }}
])

Of u kunt in plaats daarvan een datumwiskundige benadering gebruiken. Door de epochedatum toe te passen, converteert u het datumobject naar een getal waar de wiskunde kan worden toegepast:

db.collection.aggregate([
    { "$group": {
        "_id": { 
            "$subtract": [
                { "$subtract": [ "$datetime", new Date("1970-01-01") ] },
                { "$mod": [
                    { "$subtract": [ "$datetime", new Date("1970-01-01") ] },
                    1000 * 60 * 60 * 24
                ]}
            ]
        },
        "total": { "$sum": "$count" }
    }}
])

Als u op zoek bent naar intervallen vanaf een huidig ​​punt in de tijd, dan wilt u in feite de datum-wiskundebenadering en het werken in sommige conditionals via de $cond operator:

db.collection.aggregate([
    { "$match": {
        "datetime": { 
            "$gte": new Date(new Date().valueOf() - ( 1000 * 60 * 60 * 24 * 365 ))
        }
    }},
    { "$group": {
        "_id": null,
        "24hours": { 
            "$sum": {
                "$cond": [
                    { "$gt": [
                        { "$subtract": [ "$datetime", new Date("1970-01-01") ] },
                        new Date().valueOf() - ( 1000 * 60 * 60 * 24 )
                    ]},
                    "$count",
                    0
                ]
            }
        },
        "30days": { 
            "$sum": {
                "$cond": [
                    { "$gt": [
                        { "$subtract": [ "$datetime", new Date("1970-01-01") ] },
                        new Date().valueOf() - ( 1000 * 60 * 60 * 24 * 30 )
                    ]},
                    "$count",
                    0
                ]
            }
        },
        "OneYear": { 
            "$sum": {
                "$cond": [
                    { "$gt": [
                        { "$subtract": [ "$datetime", new Date("1970-01-01") ] },
                        new Date().valueOf() - ( 1000 * 60 * 60 * 24 * 365 )
                    ]},
                    "$count",
                    0
                ]
            }
        }
    }}
])

Het is in wezen dezelfde benadering als het SQL-voorbeeld, waarbij de query voorwaardelijk evalueert of de datumwaarde binnen het vereiste bereik valt en beslist of de waarde al dan niet aan de som wordt toegevoegd.

De enige toevoeging hier is de extra $match fase om de vraag te beperken tot alleen die items die mogelijk binnen het maximale bereik van één jaar vallen waar u om vraagt. Dat maakt het een beetje beter dan de gepresenteerde SQL, omdat een index kan worden gebruikt om die waarden eruit te filteren en je niet "brute force" hoeft te gebruiken door niet-overeenkomende gegevens in de verzameling.

Altijd een goed idee om de invoer te beperken met $match bij gebruik van een aggregatiepijplijn.



  1. Volgende stop - Een datapijplijn bouwen van Edge naar Insight

  2. Koppelen en maken van MongoDB-joins met SQL:deel 1

  3. Controleer het huidige aantal verbindingen met MongoDb

  4. Ontvang de ingestelde waarde van Redis met RedisTemplate