MongoDB
 sql >> Baza danych >  >> NoSQL >> MongoDB

Potrzebujesz znaleźć najczęściej występującą wartość pola w agregacie

Cóż, nie możesz tak po prostu „pogodzić się”. operatorów jako $mode nie jest operatorem agregacji, a jedyne rzeczy, których możesz użyć, to te, które faktycznie istnieje .

Aby więc zwrócić wartość kategorii w zgrupowanym okresie, który występuje najczęściej, należy najpierw pogrupować każdą z tych wartości i zwrócić liczbę wystąpień. Następnie możesz uporządkować te wyniki według tej liczby i zwrócić wartość kategorii, która zarejestrowała najwyższą liczbę w tym okresie:

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

Więc $group zarówno dla daty, jak i kategorii i zachowaj liczbę kategorii za pośrednictwem $sum . Następnie $sort więc największa „liczba” jest na górze dla każdej zgrupowanej daty. I na koniec użyj $first kiedy zastosujesz inną $group jest to po prostu stosowane do samej daty, aby zwrócić kategorię z największą liczbą dla każdej daty.

Nie daj się skusić operatorom takim jak $max ponieważ nie działają tutaj. Kluczową różnicą jest „związany” związek z „rekordem/dokumentem” wytworzonym dla każdej wartości kategorii. Nie chodzi więc o maksymalną „liczbę” lub maksymalną wartość „kategorii”, ale o wartość kategorii, która „wyprodukowała” największą liczbę. Stąd istnieje $sort potrzebne tutaj.

Na koniec kilka nawyków, które „powinieneś” przełamać:

  • Nie używaj danych instancji daty w formacie innym niż UTC jako danych wejściowych, chyba że naprawdę wiesz, co robisz. Daty będą zawsze konwertowane na UTC, więc przynajmniej w zestawieniach testowych powinieneś przyzwyczaić się do określania wartości daty w ten sposób.

  • W drugą stronę może wyglądać trochę czyściej, ale rzeczy takie jak 1000 * 60 * 60 są o wiele bardziej opisowym kodem tego, co robi niż 3600000 . Ta sama wartość, ale jedna forma na pierwszy rzut oka wskazuje na jednostki czasu.

  • Składanie _id gdy istnieje tylko jedna wartość, może również mylić problemy. Więc nie ma sensu uzyskiwać dostępu do _id.dt gdyby to była jedyna obecna wartość. Kiedy jest więcej niż jedna właściwość w _id to jest w porządku. Ale pojedyncze wartości należy po prostu przypisać z powrotem do _id sam. Nic nie zyskało inaczej, a singiel jest całkiem jasny.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. MongoDB Agregat() - błąd TypeError:Nie można wywołać metody 'forEach' o niezdefiniowanej

  2. Jak znaleźć numer wiersza w posortowanej kolekcji MongoDB, aby obliczyć jego percentyl?

  3. MongoDB przejmuje mLab  —  Jakie są różne alternatywy hostingu MongoDB?

  4. Mongodb php otrzymuje identyfikator nowego dokumentu?

  5. Policz unikalne wartości w tablicy modelu w MongoDB