Domanda

Ho una raccolta contenente un campo di data.Voglio raggrupparlo con Dayofmonth ma al momento della proiezione voglio proiettare la data completa e il conteggio associato.

Ho una raccolta di raw in MongoDB contenente un timestamp (campo data) Questa è la mia query di aggregazione:

db.raw.aggregate(
{
    "$match" : { "Timestamp":{$gte:new Date("2012-05-30T00:00:00.000Z"),$lt:new Date("2014-05-31T00:00:00.000Z")}}
},
{ 
    $group: 
    { 
        _id: { ApplicationId: "$ApplicationId", date: {$dayOfMonth: '$Timestamp'}   }, 
        count: { $sum: 1 } 
    }
}
)
.

Nella query di cui sopra sto raggruppando con Dyhofmonth, ma come posso proiettare la data con il conteggio?

È stato utile?

Soluzione

I tuoi valori "Timestamp" sono chiaramente punti reali nel tempo, quindi non c'è davvero una "data completa" per tornare. Potete solo "fare la matematica" in base all'intervallo di date che stai applicando e i valori "giorno del mese" restituiti mentre elabora i risultati restituiti.

Ma alternativamente potresti semplicemente "applicare la matematica" ai valori della data in ordine arrotondando i valori "Timestamp" fino al giorno. I valori restituiti non sono più oggetti datario, ma sono i valori millisecond dai valori epocali, quindi è relativamente facile da "seminare" le funzioni di Data:

db.raw.aggregate([
    { "$match" : { 
        "Timestamp":{
            "$gte": new Date("2012-05-30"), 
            "$lt": new Date("2014-05-31")
        }
    }},
    { "$group": {
        "_id": {
            "$subtract": [
                { "$subtract": [ "$Timestamp", new Date("1970-01-01") ] },
                { "$mod": [
                    { "$subtract": [ "$Timestamp", new Date("1970-01-01") ] },
                    1000 * 60 * 60 * 24
                ])
            ]
        },
        "count": { "$sum": 1 }
    }}
])
.

Quindi quando si sottrae un oggetto datario da un'altra la differenza è milliseconds viene restituito come un numero. Quindi questo normalizza solo per Epoch secondi sottraendo la data dell'epoca. Il resto è la data di base matematica per arrotondare il risultato al giorno corrente.

Alternativamente di nuovo è possibile utilizzare gli altri operatori di aggregazione di altri data e concatenarsi a una stringa, ma di solito ci sarebbe stato un po 'più di lavoro coinvolto a meno che tali valori fossero per uso diretto:

db.raw.aggregate([
    { "$match" : { 
        "Timestamp":{
            "$gte": new Date("2012-05-30"), 
            "$lt": new Date("2014-05-31")
        }
    }},
    { "$group": {
        "_id": {
            "$concat": [
                 { "$substr": [{ "$year": "$Timestamp" },0,4] },
                 "-",
                 { "$substr": [{ "$month": "$Timestamp" },0,2] },
                 "-",
                 { "$substr": [{ "$dayOfMonth": "$Timestamp" },0,2] }
            ]
        },
        "count": { "$sum": 1 }
    }}
])
.

Altri suggerimenti

Neil Lunn ha una grande risposta. Loro un altro approccio che puoi usare:

db.raw.aggregate([
    {
        "$match" : 
            {   
                "Timestamp":{"$gte": new Date("2012-05-30"), "$lt": new Date("2014-07-31")}
            }
    },
    { 
        "$group" :
            {   
                "_id":{"$dayOfMonth": "$Timestamp"},
                "Date":{"$first":"$Timestamp"},
                "count": { "$sum": 1 }
            }
    }
])
.

ti restituirà la data. Spero che questo ti aiuti.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top