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

Max e gruppo a Mongodb

Per ottenere il risultato desiderato, inizia scomponendo la query SQL iniziando con la sottoquery:

Select *
from tblData 
Where TFN in (Select TFN From @tmpTFNList) and TrendDate between @StartDate AND @EndDate

Segue la query mongo equivalente:

db.getCollection("_core.data").aggregate([
    {
        "$match": {
            "TFN": { "$in": tmpTFNList },
            "TrendDate": {
                "$gte": startDate,
                "$lte": endDate
            }
        }
    }
])

Il $group equivalente aggregato di

Select TFN, Max(Impressions) MaxImpression 
from tblData 
Where TFN in (Select TFN From @tmpTFNList) and TrendDate between @StartDate AND @EndDate
Group by TFN 

segue

db.getCollection("_core.data").aggregate([
    {
        "$match": {
            "TFN": { "$in": tmpTFNList },
            "TrendDate": {
                "$gte": startDate,
                "$lte": endDate
            }
        }
    },
    {
        "$group": {
            "_id": "$TFN",
            "MaxImpression": { "$max": "$Impression" }
        }
    }
])

Le prime 5 query

Select Top 5 a.TFN, a.MaxImpression as MaxCount from ( 
    Select TFN, Max(Impressions) MaxImpression 
    from tblData 
    Where TFN in (Select TFN From @tmpTFNList) 
        and TrendDate between @StartDate AND @EndDate
    Group by TFN 
) a

è possibile con $limit operatore e la selezione dei campi tramite il $project fase come

db.getCollection("_core.data").aggregate([
    { /* WHERE TFN in list AND TrendDate between DATES */
        "$match": {
            "TFN": { "$in": tmpTFNList },
            "TrendDate": {
                "$gte": startDate,
                "$lte": endDate
            }
        }
    },
    { /* GROUP BY TFN */
        "$group": {
            "_id": "$TFN",
            "MaxImpression": { "$max": "$Impression" }
        }
    },
    { "$limit": 5 }, /* TOP 5 */
    { /* SELECT a.MaxImpression as MaxCount */
        "$project": {
            "TFN": "$_id",
            "_id": 0,
            "MaxCount": "$MaxImpression"
        }
    }
])

AGGIORNAMENTO

Per ottenere il risultato desiderato dal campione in questa modifica , hai bisogno di un extra $sort pipeline prima del $group dove ordina i documenti in base a TrendDate e Impression campi, entrambi in ordine decrescente.

Dovrai quindi utilizzare il $first operatore accumulatore all'interno del $group fase della pipeline per ottenere la massima impressione poiché avrai un flusso ordinato di documenti nella tua pipeline.

Prendi in considerazione l'esecuzione dell'operazione aggregata rivista come:

db.getCollection('collection').aggregate([
    { 
        "$match": {
            "TFN": { "$in": tmpTFNList },
            "TrendDate": {
                "$gte": startDate,
                "$lte": endDate
            }
        }
    },
    { "$sort": { "TrendDate": -1, "Impression": -1 } },
    {  
        "$group": {
            "_id": "$TFN",
            "MaxImpression": { "$first": "$Impression" }
        }
    },
    { "$limit": 5 }, 
    {   
        "$project": {
            "TFN": "$_id",
            "_id": 0,
            "MaxCount": "$MaxImpression"
        }
    }
])

Risultato campione

/* 1 */
{
    "TFN" : 84251456,
    "MaxCount" : 22
}

/* 2 */
{
    "TFN" : 84251455,
    "MaxCount" : 35
}