MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

Sie müssen den am häufigsten vorkommenden Wert eines Felds in einem Aggregat finden

Nun, Sie können sich nicht einfach "versöhnen". Operatoren als $mode ist kein Aggregationsoperator, und die einzigen Dinge, die Sie verwenden können, sind diejenigen, die tatsächlich existieren .

Um also den Kategoriewert innerhalb des gruppierten Zeitraums zurückzugeben, der am häufigsten vorkommt, ist es notwendig, zuerst nach jedem dieser Werte zu gruppieren und die Anzahl der Vorkommen zurückzugeben. Dann können Sie diese Ergebnisse nach dieser Anzahl sortieren und den Kategoriewert zurückgeben, der die höchste Anzahl innerhalb dieses Zeitraums verzeichnet hat:

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

Also $group sowohl auf Datum als auch auf Kategorie und behält die Kategorieanzahl über $sum . Dann $sort die größte "Zählung" steht also für jedes gruppierte Datum oben. Und schließlich verwenden Sie $first wenn Sie eine andere $group anwenden das wird nur auf das Datum selbst angewendet, um die Kategorie mit der größten Anzahl für jedes Datum zurückzugeben.

Lassen Sie sich nicht von Operatoren wie $max verführen da sie hier nicht funktionieren. Der Hauptunterschied ist die "gebundene" Beziehung zu dem "Datensatz/Dokument", das für jeden Kategoriewert erstellt wird. Es ist also nicht die gewünschte maximale "Anzahl" oder der maximale "Kategorie"-Wert, sondern der Kategoriewert, der die größte Anzahl "erzeugt". Daher gibt es einen $sort hier benötigt.

Abschließend einige Gewohnheiten, die Sie brechen "sollten":

  • Verwenden Sie keine Datumsinstanzdaten im Nicht-UTC-Format als Eingabe, es sei denn, Sie wissen wirklich, was Sie tun. Datumsangaben werden immer in UTC konvertiert, daher sollten Sie sich zumindest in Testlisten daran gewöhnen, den Datumswert auf diese Weise anzugeben.

  • Umgekehrt sieht es vielleicht etwas sauberer aus, aber Dinge wie 1000 * 60 * 60 sind viel besser beschreibender Code dessen, was es tut, als 3600000 . Gleicher Wert, aber ein Formular zeigt die Zeiteinheiten auf einen Blick an.

  • Zusammensetzen von _id Wenn es nur einen einzigen Wert gibt, kann dies ebenfalls zu Verwirrung führen. Es macht also wenig Sinn, auf _id.dt zuzugreifen wenn das der einzige vorhandene Wert wäre. When ist mehr als eine einzelne Eigenschaft innerhalb von _id dann ist es in Ordnung. Aber einzelne Werte sollten einfach gleich wieder _id zugewiesen werden allein. Sonst nichts gewonnen, und Single ist ganz klar.