Spring Data MongoDB 六:进阶Aggregation操作(上)

来源:互联网 发布:linux 编译动态库 编辑:程序博客网 时间:2024/06/06 03:46

一、Aggregate简介                                                                           

      db.collection.aggregate()是基于数据处理的聚合管道,每个文档通过一个由多个阶段(stage)组成的管道,可以对每个阶段的管道进行分组、过滤等功能,然后经过一系列的处理,输出相应的结果。

          

      1db.collection.aggregate()可以多个管道,能方便的进行数据的处理。

      2db.collection.aggregate()使用了MongoDB内置的原生操作,聚合效率非常高,支持类似于SQL Group By操作的功能,而不再需要用户编写自定义的JavaScript例程。

      3、 每个阶段管道限制为100MB的内存。如果一个节点管道超过这个极限,mongodb将产生一个错误。为了能够在处理大型数据集,可以设置allowDiskUsetrue来在聚合管道节点把数据写入临时文件。这样就可以解决100MB的内存的限制。

     4db.collection.aggregate()可以作用在分片集合,但结果不能输在分片集合,MapReduce可以 作用在分片集合,结果也可以输在分片集合。

     5db.collection.aggregate()方法可以返回一个指针(cursor),数据放在内存中,直接操作。跟Mongo shell 一样指针操作。

     6db.collection.aggregate()输出的结果只能保存在一个文档中,BSON Document大小限制为16M。可以通过返回指针解决,版本2.6中后面:DB.collect.aggregate()方法返回一个指针,可以返回任何结果集的大小。


二、Aggregate pipeline 参数                                    

          今天主要是pipeline 运用到spring上

   pipeline 参数】

     pipeline 类型是Array  语法:db.collection.aggregate( [ { <stage> }, ... ] )

         $project:可以对输入文档进行添加新字段或删除现有的字段,可以自定哪些字段显示与不显示。

         $match :根据条件用于过滤数据,只输出符合条件的文档,如果放在pipeline前面,根据条件过滤数据,传输到下一个阶段管道,可以提高后续的数据处理效率。还可以放在out之前,对结果进行再一次过滤。

         $limit :用来限制MongoDB聚合管道返回的文档数

         $skip :在聚合管道中跳过指定数量的文档,并返回余下的文档。

         $unwind :将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。    

         $out :必须为pipeline最后一个阶段管道,因为是将最后计算结果写入到指定的collection中。

         $group : 将集合中的文档分组,可用于统计结果,$group首先将数据根据key进行分组。

 

       MongoDB上对 pipeline 操作可以查看

           学习MongoDB 十一: MongoDB聚合(Aggregation Pipeline基础篇上)(三)

           学习MongoDB 十二: MongoDB聚合(Aggregation Pipeline基础篇-下)(四)


三、举例子并在MongoDB操作pipeline                                                                                                                      


        举例【订单】
        
[sql] view plain copy
  1. db. orders.insert([    
  2. {    
  3.         "onumber" : "001",     
  4.         "date" : "2015-07-02",     
  5.         "cname" : "zcy1",     
  6.          "items" :[ {    
  7.                    "ino" : "001",    
  8.                   "quantity" :2,     
  9.                   "price" : 4.0    
  10.                  },{    
  11.                    "ino" : "002",    
  12.                   "quantity" : 4,     
  13.                   "price" : 6.0    
  14.                 }    
  15.                 ]    
  16. },{    
  17.          "onumber" : "002",     
  18.         "date" : "2015-07-02",     
  19.         "cname" : "zcy2",     
  20.          "items" :[ {    
  21.                   "ino" : "003",    
  22.                   "quantity" :1,     
  23.                   "price" : 4.0    
  24.                    },{    
  25.                   "ino" : "002",    
  26.                   "quantity" :6,     
  27.                   "price" : 6.0    
  28.                  }    
  29.                ]    
  30. },{    
  31.          "onumber" : "003",     
  32.         "date" : "2015-07-02",     
  33.         "cname" : "zcy2",     
  34.          "items" :[ {    
  35.                   "ino" : "004",    
  36.                   "quantity" :3,     
  37.                   "price" : 4.0    
  38.                    },{    
  39.                   "ino" : "005",    
  40.                   "quantity" :1,     
  41.                   "price" : 6.0    
  42.                  }    
  43.                ]    
  44. },{    
  45.          "onumber" : "004",     
  46.         "date" : "2015-07-02",     
  47.         "cname" : "zcy2",     
  48.          "items" :[ {    
  49.                   "ino" : "001",    
  50.                   "quantity" :3,     
  51.                   "price" : 4.0    
  52.                    },{    
  53.                   "ino" : "003",    
  54.                   "quantity" :1,     
  55.                   "price" : 6.0    
  56.                  }    
  57.                ]    
  58. }  
  59. ])  

       
        【MongoDB  Aggregation】
             
             我们需要查询订单号为001,002,003中的订单详情各个产品卖出多少个,并且过滤掉数量小于1的产品

[sql] view plain copy
  1. > db.orders.aggregate([  
  2. ... {$match:{"onumber":{$in:["001","002""003"]}}},  
  3. ... {$unwind:"$items"},  
  4. ... {$group:{_id:"$items.ino",total:{$sum:"$items.quantity"}}},  
  5. ... {$match:{total:{$gt:1}}}  
  6. ... ]);  
  7. "_id" : "004""total" : 3 }  
  8. "_id" : "002""total" : 10 }  
  9. "_id" : "001""total" : 2 }  


       

四、AggregationOutput                                                                                                                

           

             Spring Data  MongoDB 项目提供与MongoDB文档数据库的集成。如果对环境的搭建不清楚可以先看

            
            Spring Data MongoDB 一:入门篇(环境搭建、简单的CRUD操作)

        

        我们先介绍Mongo本身提供的com.mongodb.AggregationOutput进行分组查询,下一篇会介绍Spring Data MongoDB模板封装的Aggregation方法,我们直接看代码

           


               通过模板获取连接,然后执行Aggregation,该方法是参数可以接受多个参数。AggregationOutput提供了一个方法results是返回了
          Iterator<DBObject>


           【实现类】

                 
[java] view plain copy
  1. @Override  
  2. public void getAggregation() {  
  3.     Set<String> onumberSet=new HashSet<String>();  
  4.     onumberSet.add("001");  
  5.     onumberSet.add("002");  
  6.     onumberSet.add("003");  
  7.     //过滤条件  
  8.     DBObject queryObject=new BasicDBObject("onumber"new BasicDBObject("$in",onumberSet));  
  9.     DBObject queryMatch=new BasicDBObject("$match",queryObject);  
  10.     //展开数组  
  11.     DBObject queryUnwind=new BasicDBObject("$unwind","$items");  
  12.     //分组统计  
  13.     DBObject groupObject=new BasicDBObject("_id",new BasicDBObject("ino","$items.ino"));  
  14.     groupObject.put("total"new BasicDBObject("$sum","$items.quantity"));  
  15.     DBObject  queryGroup=new BasicDBObject("$group",groupObject);  
  16.     //过滤条件  
  17.     DBObject finalizeMatch=new BasicDBObject("$match",new BasicDBObject("total",new BasicDBObject("$gt",1)));  
  18.   
  19.     AggregationOutput  output=mongoTemplate.getCollection("orders").aggregate(queryMatch,queryUnwind,queryGroup,finalizeMatch);  
  20.     for (Iterator<DBObject> iterator = output.results().iterator(); iterator.hasNext();) {  
  21.         DBObject obj =iterator.next();  
  22.         System.out.println(obj.toString());  
  23.     }  
  24.          }  

     【测试类】
             
[java] view plain copy
  1. public class TestOrders {  
  2.      private static OrdersDao ordersDaoImpl;    
  3.         private static  ClassPathXmlApplicationContext  app;    
  4.         @BeforeClass      
  5.         public static void initSpring() {     
  6.             try {           
  7.              app = new ClassPathXmlApplicationContext("classpath:applicationContext-mongo.xml");      
  8.              ordersDaoImpl = (OrdersDao) app.getBean("ordersDaoImpl");     
  9.             } catch (Exception e) {    
  10.                 e.printStackTrace();    
  11.             }    
  12.                }     
  13.             
  14.             @Test     
  15.             public void testAggregation()    
  16.             {    
  17.                 ordersDaoImpl.getAggregation();  
  18.                   
  19.             }    
  20. }  

     【结果】
                  
                

原文地址:http://blog.csdn.net/congcong68/article/category/5681741
阅读全文
0 0
原创粉丝点击