MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

Raggruppa per intervalli di date

Sono disponibili operatori di aggregazione di date per il framework di aggregazione di MongoDB. Quindi, ad esempio, un $dayOfYear viene utilizzato per ottenere quel valore dalla data da utilizzare nel raggruppamento:

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

Oppure puoi utilizzare un approccio matematico per date. Applicando la data epoch si converte l'oggetto data in un numero a cui è possibile applicare la matematica:

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" }
    }}
])

Se quello che stai cercando sono gli intervalli da un momento attuale, quello che vuoi è fondamentalmente l'approccio matematico delle date e lavorare in alcuni condizionali tramite il $cond operatore:

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
                ]
            }
        }
    }}
])

È essenzialmente lo stesso approccio dell'esempio SQL, in cui la query valuta in modo condizionale se il valore della data rientra nell'intervallo richiesto e decide se aggiungere o meno il valore alla somma.

L'unica aggiunta qui è il $match aggiuntivo fase per limitare la query in modo che agisca solo su quegli elementi che potrebbero rientrare nell'intervallo massimo di un anno richiesto. Ciò lo rende un po' migliore rispetto all'SQL presentato in quanto un indice potrebbe essere utilizzato per filtrare quei valori e non è necessario "forzare bruta" attraverso i dati non corrispondenti nella raccolta.

È sempre una buona idea limitare l'input con $match quando si utilizza una pipeline di aggregazione.