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. }  

    结果:

       

  • 相关阅读:
    (转)Java 详解 JVM 工作原理和流程
    sql复杂查询语句总结
    公众平台服务号、订阅号、企业号的相关说明
    新公司注册流程
    认缴出资额和实缴出资额的区别
    ***iOS学习之Table View的简单使用和DEMO示例(共Plain普通+Grouped分组两种)
    APP后端处理视频的方案
    iOS应用程序生命周期(前后台切换,应用的各种状态)详解
    app后端搜索入门
    APP后端处理表情的一些技巧
  • 原文地址:https://www.cnblogs.com/shihaiming/p/7691905.html
Copyright © 2011-2022 走看看