MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

Необходимо е да се намери най-често срещаната стойност на поле в агрегат

Е, не можете просто да се "гримирате". оператори като $mode не е оператор за агрегиране и единствените неща, които можете да използвате, са тези, които действително съществуват .

Така че, за да се върне стойността на категорията в рамките на групирания период от време, който се среща най-често, е необходимо първо да се групира всяка от тези стойности и да се върне броят на повторенията. След това можете да подредите тези резултати по този брой и да върнете стойността на категорията, която е записала най-висок брой в рамките на този период:

    // 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 на дата и категория и запазване на броя на категориите чрез $sum . След това $sort така че най-големият "брой" е отгоре за всяка групирана дата. И накрая използвайте $first когато приложите друга $group който просто се прилага към самата дата, за да върне тази категория с най-голям брой за всяка дата.

Не се изкушавайте от оператори като $max тъй като те не работят тук. Ключовата разлика е „обвързаното“ отношение към „запис/документ“, произведен за всяка стойност на категория. Така че това не е максималния "брой", който искате, или максималната стойност на "категория", а стойността на категорията, която "произведе" най-големия брой. Следователно има $sort необходими тук.

И накрая някои навици, които „трябва“ да прекъснете:

  • Не използвайте данни за екземпляр на дата във формат извън UTC като вход, освен ако наистина не знаете какво правите. Датите винаги ще се преобразуват в UTC, така че поне в тестовите списъци трябва да свикнете да указвате стойността на датата по този начин.

  • Може да изглежда малко по-изчистено по друг начин, но неща като 1000 * 60 * 60 са много по-описателен код за това, което прави от 3600000 . Същата стойност, но една форма е показателна за единиците за време с един поглед.

  • Съставен _id когато има само една стойност също може да обърка проблемите. Така че няма голям смисъл от достъп до _id.dt ако това беше единствената налична стойност. Когато има повече от едно свойство в _id тогава е добре. Но единичните стойности трябва просто да бъдат присвоени обратно на _id сам. Нищо не е спечелено в противен случай и сингълът е съвсем ясен.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Чернови на документи в Mongo

  2. Каква е разликата между Limit и BatchSize в MongoCursor?

  3. Как да използвате findAndModify в php и mongodb

  4. Mongoose не запазва вложен обект

  5. MongoDB + nodejs:как да потърся заявка за полетата на ISODate?