zoukankan      html  css  js  c++  java
  • MongoDB 聚合Group(一)

    原文:http://blog.csdn.net/congcong68/article/details/45012717

      一.简介 

        db.collection.group()使用JavaScript,它受到了一些性能上的限制。大多数情况下,$ group在Aggregation Pipeline提供了一种具有较少的限制适用的替代。可以通过指定的键的集合中的文档和执行简单的聚合函数。在2.2版本中,返回的数组可以包含最多20000个元素;即最多20000个独特的分组。

        我们比较熟悉的group by 的sql语句select key from table  groupby key,而mongoDB没提供SQL那样通过Group By就轻松实现数据库的分组功能,我们通过接口来实现的

       db.collection.group({ key, reduce, initial[, keyf] [, cond] [, finalize] })

       

    key

    作为分组的key

    reduce

    一个聚合函数操作文档的分组操作期间。这些函数可以返回一个sum或count。该函数接受两个参数:当前文档和这个群体聚集的结果文档。

    initial

    初始化聚合结果文档变量,为空时自动为每列提供初始变量。

    keyf

    可选。替代的key 字段。指定一个函数创建一个“key object”作为分组的key。使用keyf而是通过group by领域而不是现有的文档域键组。

    cond

    过滤条件

    finalize

    在db.collection.group()返回最终结果之前,此功能可以修改的结果文档或替换的结果文档作为一个整体。

      

      

    二.Mongo VUE操作Group By

      1.MonogoDB数据库中添加了订单的数据

    [html] view plain copy
     
    1. /* 0 */  
    2. {  
    3.  "_id" : ObjectId("552a330e05c27486b9b9b650"),  
    4.  "_class" : "com.mongo.model.Orders",  
    5.  "onumber" : "002",  
    6.  "date" : ISODate("2014-01-03T16:03:00Z"),  
    7.  "cname" : "zcy",  
    8.  "item" : {  
    9.    "quantity" : 1,  
    10.    "price" : 4.0,  
    11.    "pnumber" : "p002"  
    12.   }  
    13. }  
    14.    
    15. /* 1 */  
    16. {  
    17.  "_id" : ObjectId("552a331d05c275d8590a550d"),  
    18.  "_class" : "com.mongo.model.Orders",  
    19.  "onumber" : "003",  
    20.  "date" : ISODate("2014-01-04T16:03:00Z"),  
    21.  "cname" : "zcy",  
    22.  "item" : {  
    23.    "quantity" : 10,  
    24.    "price" : 2.0,  
    25.    "pnumber" : "p001"  
    26.   }  
    27. }  
    28.    
    29. /* 2 */  
    30. {  
    31.  "_id" : ObjectId("552a333105c2f28194045a72"),  
    32.  "_class" : "com.mongo.model.Orders",  
    33.  "onumber" : "003",  
    34.  "date" : ISODate("2014-01-04T16:03:00Z"),  
    35.  "cname" : "zcy",  
    36.  "item" : {  
    37.    "quantity" : 30,  
    38.    "price" : 4.0,  
    39.    "pnumber" : "p002"  
    40.   }  
    41. }  
    42.    
    43. /* 3 */  
    44. {  
    45.  "_id" : ObjectId("552a333f05c2b62c01cff50e"),  
    46.  "_class" : "com.mongo.model.Orders",  
    47.  "onumber" : "004",  
    48.  "date" : ISODate("2014-01-05T16:03:00Z"),  
    49.  "cname" : "zcy",  
    50.  "item" : {  
    51.    "quantity" : 5,  
    52.    "price" : 4.0,  
    53.    "pnumber" : "p002"  
    54.   }  
    55. }  

    2.MongoDB实现分组并统计

      1)我们要对日期和产品编码进行分组,并计算相同的产品的数量

        Sql语句:Select date, pnumber,sum(quantity) as total from orders,items group by date, pnumber(少了两张表的关联的条件)

        MongoDB:

           db.orders.group({

              key: { date:1,'item.pnumber':1},

              initial : {"total":0},

             reduce : function Reduce(doc, out) {

            out.total+=doc.item.quantity

       } });

    结果:

      

      2)实现一天卖出了多少个产品,金额是多少,平均价格是多少

        db.orders.group({

           key: {date:1},

          initial :{"total":0,"money":0},

         reduce : function Reduce(doc, out) {

         out.total+=doc.item.quantity;

              out.money+=doc.item.quantity*doc.item.price;

            },

        finalize : function Finalize(out) {

             out.avg=out.money/out.total

             returnout;

        }

      });

     结果:

        

     3)keyf的使用

       keyf 对日期进行处理并以作为key来进来分组

     db.orders.group({

       keyf: function (doc){

       return{'month':doc.date.getMonth()+1};

     },

     initial :{"total":0,"money":0},

     reduce : function Reduce(doc, out) {

        out.total+=doc.item.quantity;

              out.money+=doc.item.quantity*doc.item.price;

            

    },

     finalize : function Finalize(out) {

             out.avg=out.money/out.total

             returnout;

      }

    });

    结果:

      

    三.Java MongoDB 实现

           Spring Data MongoDB 提供了Group有几个接口
           
       
        GroupCommand  groupCommand=new GroupCommand(inputCollection, keys, condition, initial, reduce, finalize);
     

        1)我们要对日期和产品编码进行分组,并计算相同的产品的数量

               

    [java] view plain copy
     
    1. <strong>  </strong>     @Override  
    2.     public void getGroupCount(String collectionName) {  
    3.           
    4.         BasicDBObject key = new BasicDBObject();   
    5.         key.put("date", 1);  
    6.         key.put("item.pnumber", 1);  
    7.         //条件  
    8.         BasicDBObject cond = new BasicDBObject();    
    9.         //初始化  
    10.         BasicDBObject initial = new BasicDBObject();    
    11.         initial.append("total", 0);    
    12.         //reduce  
    13.         String reduce = "function Reduce(doc, out) { " +    
    14.                 "  out.total+=doc.item.quantity;" +    
    15.                 "}";    
    16.           
    17.         SimpleDateFormat format=new SimpleDateFormat("yyyy-mm-dd");  
    18.         BasicDBList groupList=(BasicDBList) mongoTemplate.getCollection(collectionName).group(key, cond, initial, reduce);  
    19.         if(groupList!=null&&groupList.size()>0){  
    20.             System.out.println("date  item.pnumber  total");  
    21.             for(int i=0;i<groupList.size();i++){   
    22.                 BasicDBObject obj=(BasicDBObject) groupList.get(i);  
    23.                 System.out.println(format.format(obj.getDate("date"))+"  "+obj.getString("item.pnumber")+"  "+obj.getInt("total"));  
    24.             }  
    25.         }  
    26.     }  

    结果:

       

     

       2)实现一天卖出了多少个产品,金额是多少,平均价格是多少

          

    [java] view plain copy
     
    1.        @Override  
    2. public void getGroupAvg(String collectionName) {  
    3.       
    4.     BasicDBObject key = new BasicDBObject();   
    5.     key.put("date", 1);  
    6.       
    7.     //条件  
    8.     BasicDBObject cond = new BasicDBObject();    
    9.     //初始化  
    10.     BasicDBObject initial = new BasicDBObject();    
    11.     initial.append("total", 0);   
    12.     initial.append("money", 0.0);  
    13.       
    14.     //reduce  
    15.     String reduce = "function Reduce(doc, out) { " +    
    16.             "  out.total+=doc.item.quantity;" +   
    17.             "   out.money+=doc.item.quantity*doc.item.price;" +  
    18.             "}";   
    19.       
    20.     String finalize="function Finalize (out) { " +    
    21.         "  out.avg=out.money/out.total;" +   
    22.         "   return out;" +  
    23.         "}";          
    24.     SimpleDateFormat format=new SimpleDateFormat("yyyy-mm-dd");  
    25.     BasicDBList groupList=(BasicDBList) mongoTemplate.getCollection(collectionName).group(key, cond, initial, reduce, finalize);  
    26.     if(groupList!=null&&groupList.size()>0){  
    27.         System.out.println("date  total  money  avg");  
    28.         for(int i=0;i<groupList.size();i++){   
    29.             BasicDBObject obj=(BasicDBObject) groupList.get(i);  
    30.             System.out.println(format.format(obj.getDate("date"))+"  "+obj.getInt("total")+"  "+obj.getInt("money")+"  "+obj.getDouble("avg"));  
    31.         }  
    32.     }  
    33.       
    34. }  

    结果:

       

  • 相关阅读:
    1、编写一个简单的C++程序
    96. Unique Binary Search Trees
    python 操作redis
    json.loads的一个很有意思的现象
    No changes detected
    leetcode 127 wordladder
    django uwsgi websocket踩坑
    you need to build uWSGI with SSL support to use the websocket handshake api function !!!
    pyinstaller 出现str error
    数据库的读现象
  • 原文地址:https://www.cnblogs.com/shihaiming/p/7691905.html
Copyright © 2011-2022 走看看