sql >> Database >  >> NoSQL >> MongoDB

Moet de meest voorkomende waarde van een veld in een aggregaat vinden

Nou, je kunt niet zomaar "make-up". operators als $mode is geen aggregatie-operator, en de enige dingen die u kunt gebruiken zijn diegene die echt bestaan .

Dus om de categoriewaarde te retourneren binnen de gegroepeerde tijdsperiode die het meest voorkomt, is het noodzakelijk om eerst te groeperen op elk van die waarden en het aantal voorkomens terug te geven. Vervolgens kunt u deze resultaten op dat aantal sorteren en de categoriewaarde retourneren die het hoogste aantal binnen die periode heeft geregistreerd:

    // 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" }
    }}

Dus $group op zowel datum als categorie en behoud de categorietelling via $sum . Dan moet je $sort dus de grootste "telling" staat bovenaan voor elke gegroepeerde datum. En gebruik ten slotte $first wanneer u een andere $group toepast dat wordt alleen toegepast op de datum zelf, om die categorie met het grootste aantal voor elke datum terug te geven.

Laat u niet verleiden door operators zoals $max aangezien ze hier niet werken. Het belangrijkste verschil is de "gebonden" relatie met het "record/document" dat voor elke categoriewaarde wordt geproduceerd. Het is dus niet de maximale "telling" die u wilt of de maximale "categorie"-waarde, maar in plaats daarvan de categoriewaarde die de grootste telling "produceerde". Daarom is er een $sort hier nodig.

Eindelijk een paar gewoonten die je "moet" doorbreken:

  • Gebruik geen datum-instantiegegevens zonder UTC-indeling als invoer, tenzij u echt weet wat u doet. Datums worden altijd geconverteerd naar UTC, dus in testvermeldingen moet u er in ieder geval aan wennen om de datumwaarde op die manier op te geven.

  • De andere kant op ziet het er misschien wat schoner uit, maar dingen als 1000 * 60 * 60 zijn veel meer beschrijvende code van wat het doet dan 3600000 . Dezelfde waarde, maar één vorm is in één oogopslag indicatief voor de tijdseenheden.

  • Samengestelde _id wanneer er slechts één waarde is, kan dit ook voor verwarring zorgen. Het heeft dus weinig zin om toegang te krijgen tot _id.dt als dat de enige aanwezige waarde was. Wanneer is meer dan een enkele eigenschap binnen _id dan is het goed. Maar enkele waarden moeten gewoon weer worden toegewezen aan _id alleen. Niets anders gewonnen, en single is vrij duidelijk.




  1. Mongodb:documenten sorteren op array-objecten

  2. Redis SYNC en EXEC

  3. mongo createIndex achtergrond blokkeert de shell

  4. Datumnotatie mangoest