MongoDB 聚合Group(一)

转自: https://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数据库中添加了订单的数据

/* 0 */
{
 "_id" : ObjectId("552a330e05c27486b9b9b650"),
 "_class" : "com.mongo.model.Orders",
 "onumber" : "002",
 "date" : ISODate("2014-01-03T16:03:00Z"),
 "cname" : "zcy",
 "item" : {
   "quantity" : 1,
   "price" : 4.0,
   "pnumber" : "p002"
  }
}

/* 1 */
{
 "_id" : ObjectId("552a331d05c275d8590a550d"),
 "_class" : "com.mongo.model.Orders",
 "onumber" : "003",
 "date" : ISODate("2014-01-04T16:03:00Z"),
 "cname" : "zcy",
 "item" : {
   "quantity" : 10,
   "price" : 2.0,
   "pnumber" : "p001"
  }
}

/* 2 */
{
 "_id" : ObjectId("552a333105c2f28194045a72"),
 "_class" : "com.mongo.model.Orders",
 "onumber" : "003",
 "date" : ISODate("2014-01-04T16:03:00Z"),
 "cname" : "zcy",
 "item" : {
   "quantity" : 30,
   "price" : 4.0,
   "pnumber" : "p002"
  }
}

/* 3 */
{
 "_id" : ObjectId("552a333f05c2b62c01cff50e"),
 "_class" : "com.mongo.model.Orders",
 "onumber" : "004",
 "date" : ISODate("2014-01-05T16:03:00Z"),
 "cname" : "zcy",
 "item" : {
   "quantity" : 5,
   "price" : 4.0,
   "pnumber" : "p002"
  }
}

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)我们要对日期和产品编码进行分组,并计算相同的产品的数量

           

<strong>  </strong>     @Override
    public void getGroupCount(String collectionName) {

        BasicDBObject key = new BasicDBObject(); 
        key.put("date", 1);
        key.put("item.pnumber", 1);
        //条件
        BasicDBObject cond = new BasicDBObject();  
        //初始化
        BasicDBObject initial = new BasicDBObject();  
        initial.append("total", 0);  
        //reduce
        String reduce = "function Reduce(doc, out) { " +  
                "  out.total+=doc.item.quantity;" +  
                "}";  

        SimpleDateFormat format=new SimpleDateFormat("yyyy-mm-dd");
        BasicDBList groupList=(BasicDBList) mongoTemplate.getCollection(collectionName).group(key, cond, initial, reduce);
        if(groupList!=null&&groupList.size()>0){
            System.out.println("date  item.pnumber  total");
            for(int i=0;i<groupList.size();i++){ 
                BasicDBObject obj=(BasicDBObject) groupList.get(i);
                System.out.println(format.format(obj.getDate("date"))+"  "+obj.getString("item.pnumber")+"  "+obj.getInt("total"));
            }
        }
    }
结果:

   

 

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

      

        @Override
    public void getGroupAvg(String collectionName) {

        BasicDBObject key = new BasicDBObject(); 
        key.put("date", 1);

        //条件
        BasicDBObject cond = new BasicDBObject();  
        //初始化
        BasicDBObject initial = new BasicDBObject();  
        initial.append("total", 0); 
        initial.append("money", 0.0);

        //reduce
        String reduce = "function Reduce(doc, out) { " +  
                "  out.total+=doc.item.quantity;" + 
                "   out.money+=doc.item.quantity*doc.item.price;" +
                "}"; 

        String finalize="function Finalize (out) { " +  
            "  out.avg=out.money/out.total;" + 
            "   return out;" +
            "}";        
        SimpleDateFormat format=new SimpleDateFormat("yyyy-mm-dd");
        BasicDBList groupList=(BasicDBList) mongoTemplate.getCollection(collectionName).group(key, cond, initial, reduce, finalize);
        if(groupList!=null&&groupList.size()>0){
            System.out.println("date  total  money  avg");
            for(int i=0;i<groupList.size();i++){ 
                BasicDBObject obj=(BasicDBObject) groupList.get(i);
                System.out.println(format.format(obj.getDate("date"))+"  "+obj.getInt("total")+"  "+obj.getInt("money")+"  "+obj.getDouble("avg"));
            }
        }

    }
结果:

   


        </div>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值