sql >> Databasteknik >  >> NoSQL >> MongoDB

Behöver hitta det vanligaste värdet av ett fält i ett aggregat

Man kan inte bara "sminka sig". operatorer som $mode är inte en aggregeringsoperatör, och det enda du kan använda är de som faktiskt existerar .

Så för att returnera kategorivärdet inom den grupperade tidsperiod som förekommer mest, är det nödvändigt att först gruppera vart och ett av dessa värden och returnera antalet förekomster. Sedan kan du beställa dessa resultat efter det antalet och returnera det kategorivärde som registrerade det högsta antalet inom den perioden:

    // Filter dates
    { "$match": { 
        "dt": { 
            "$gt": new Date("October 13, 2010 12:00:00"), 
            "$lt": new Date("November 13, 2010 12:00:00")
        } 
    }},

    // Group by hour and category, with avg and count
    { "$group": {
        "_id": {
            "dt": {
                "$add": [
                    {
                        "$subtract": [
                            { "$subtract": ["$dt", new Date(0)] },
                            {
                                "$mod": [
                                    { "$subtract": ["$dt", new Date(0)] },
                                    3600000//1000 * 60 * 60
                                ]
                            }
                        ]
                    },
                    new Date(0)
                ]
            },
            "category": "$category"
        }, 
        "price": { "$avg": "$price" },
        "count": { "$sum": 1 }
    }},
    // Sort on date and count
    { "$sort": { "_id.dt": 1, "count": -1 }},

    // Group on just the date, keeping the avg and the first category
    { "$group": {
        "_id": "$_id.dt",
        "price": { "$avg": "$price"}
        "category": { "$first": "$_id.category" }
    }}

$group på både datum och kategori och behåll kategoriantalet via $sum . Sedan $sort så den största "räkningen" är överst för varje grupperat datum. Och använd slutligen $first när du använder en annan $group som bara tillämpas på själva datumet, för att returnera den kategorin med det största antalet för varje datum.

Låt dig inte frestas av operatorer som $max eftersom de inte fungerar här. Den viktigaste skillnaden är den "bundna" relationen till "posten/dokumentet" som produceras för varje kategorivärde. Det är alltså inte det maximala "antal" du vill ha eller det maximala "kategorivärdet", utan istället kategorivärdet som "producerade" det största antalet. Därför finns det en $sort behövs här.

Äntligen några vanor du "bör" bryta:

  • Använd inte dataförekomster i icke UTC-format som indata om du inte riktigt vet vad du gör. Datum kommer alltid att konverteras till UTC, så åtminstone i testlistor bör du vänja dig vid att ange datumvärdet på det sättet.

  • Det kan se lite renare ut åt andra hållet men saker som 1000 * 60 * 60 är mycket mer beskrivande kod för vad den gör än 3600000 . Samma värde, men en form är en indikation på dess tidsenheter på ett ögonblick.

  • Sammansättning av _id när det bara finns ett enda värde kan också förvirra problem. Så det finns ingen mening med att komma åt _id.dt om det var det enda värdet som fanns. När är mer än en enskild egenskap inom _id då är det bra. Men enstaka värden bör bara tilldelas direkt tillbaka till _id ensam. Inget vunnit annars, och singel är ganska tydlig.




  1. MongoDB 4.x Real Time Sync till ElasticSearch 6.x +

  2. GridFS i Spring Data MongoDB

  3. Hur man konverterar en viss dtype-objektkolumns fält till kolumn med dataram i pandor

  4. Fel vid hämtning av tweets med Tweepy