MongoTemplate聚合操作


 Aggregation簡單來說,就是提供數據統計、分析、分類的方法,這與mapreduce有異曲同工之處,只不過mongodb做了更多的封裝與優化,讓數據操作更加便捷和易用。Aggregation操作,接收指定collection的數據集,通過計算后返回result數據;一個aggregation操作,從input源數據到output結果數據,中間會依次經過多個stages,整體而言就是一個pipeline;目前有10種stages,我們稍后介紹;它還提供了豐富的Expression(表達式)來輔助計算。

聚合管道是一個基於數據處理管道概念的框架。通過使用一個多階段的管道,將一組文檔轉換為最終的聚合結果。

管道的概念

管道在Unix和Linux中一般用於將當前命令的輸出結果作為下一個命令的參數。

MongoDB的聚合管道將MongoDB文檔在一個管道處理完畢后將結果傳遞給下一個管道處理。管道操作是可以重復的。

表達式:處理輸入文檔並輸出。表達式是無狀態的,只能用於計算當前聚合管道的文檔,不能處理其它的文檔。

語法:

db.collection.aggregate(pipeline, options);

pipeline Array
語法示例:

db.school.aggregate(
[
{$match:{time:{$gt:1513612800}}},
{$group:{_id:{insituteName:"$institute",class:"$name"},count:{$sum:1}}},
{$sort:{count:-1}},
{$limit:10}]
)

這里我們介紹一下聚合框架中常用的幾個操作:
$project:修改輸入文檔的結構。可以用來重命名、增加或刪除域,也可以用於創建計算結果以及嵌套文檔。
$match:用於過濾數據,只輸出符合條件的文檔。$match使用MongoDB的標准查詢操作,放在group前相當於where使用,放在group后面相當於having使用
$sort: 排序,1升、-1降。sort一般放在group后,也就是說得到結果后再排序,如果先排序再分組沒什么意義;
$limit:用來限制MongoDB聚合管道返回的文檔數。相當於limit m,不能設置偏移量
$skip:聚合管道中跳過指定數量的文檔,並返回余下的文檔。跳過第幾個文檔
$unwind:將文檔中的某一個數組類型字段拆分成多條,每條包含數組中的一個值。
$group:將集合中的文檔分組,可用於統計結果。其中_id固定寫法:

{ _id: <expression>, <field1>: { <accumulator1> : <expression1> }, ...  

按什么字段分組,注意所有字段名前面都要加$,否則mongodb就為以為不加$的是普通常量,其中accumulator又包括以下幾個操作符:
$sum,$avg,$first,$last,$max,$min,$push,$addToSet

 如果按照多個字段分組,則字段必須都在_id對象中,可以取別名,例如上面示例,輸出結果為:
   { "_id" : { "insituteName" : "數學系",class: "一班"}, "count" : 200 }
   { "_id" : { "insituteName" : "英語系",class: "二班" }, "count" : 201 }
   如果按照一個字段分組,則可以寫為{$group:{_id:"$institute",count:{$sum:1}}},此時,查詢結果為:
   { "_id" : "數學系", "count" : 1000 }
   { "_id" : "英語系", "count" : 800 }
若沒有分組字段,則{$group:{_id:null,count:{$sum:1}}}。即:如果group by null就是 count(*)的效果

$geoNear:取某一點的最近或最遠,在LBS地理位置中有用
$out:把結果寫進新的集合中。注意1,不能寫進一個分片集合中。注意2,不能寫進

 

count:{$sum:1},1表示統計查詢結果數量,如果想統計time字段和則使用 count:{$sum:"$time"}。

聚合函數有:min,max,sum,avg

下表展示了一些聚合的表達式:

表達式 描述 實例
$sum 計算總和。 db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : "$likes"}}}])
$avg 計算平均值 db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$avg : "$likes"}}}])
$min 獲取集合中所有文檔對應值得最小值。 db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$min : "$likes"}}}])
$max 獲取集合中所有文檔對應值得最大值。 db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$max : "$likes"}}}])
$push 在結果文檔中插入值到一個數組中。 db.mycol.aggregate([{$group : {_id : "$by_user", url : {$push: "$url"}}}])
$addToSet 在結果文檔中插入值到一個數組中,但不創建副本。 db.mycol.aggregate([{$group : {_id : "$by_user", url : {$addToSet : "$url"}}}])
$first 根據資源文檔的排序獲取第一個文檔數據。 db.mycol.aggregate([{$group : {_id : "$by_user", first_url : {$first : "$url"}}}])
$last 根據資源文檔的排序獲取最后一個文檔數據 db.mycol.aggregate([{$group : {_id : "$by_user", last_url : {$last : "$url"}}}])


使用MongoTemplate操作Aggregation

    Aggregation agg = Aggregation.newAggregation(    
            Aggregation.match(criteria),//條件  
            Aggregation.group("a","b","c","d","e").count().as("f"),//分組字段    
            Aggregation.sort(sort),//排序  
            Aggregation.skip(page.getFirstResult()),//過濾  
            Aggregation.limit(pageSize)//頁數  
         );    
    AggregationResults<Test> outputType=mongoTemplate.aggregate(agg,"test",Test.class);    
    List<Test> list=outputType.getMappedResults(); 

 示例:

上面是mysql的,下面是mongoTemplate的代碼:

 mongoTemplate的代碼:

Aggregation aggregation = Aggregation.newAggregation(
            Aggregation.match(Criteria.where("agent_id").is(conditions.getAgentId()).and("order_status").is(9)),
            Aggregation.group("agentId", "orderStatus").
            count().as("totalCount").sum("amount").as("totalAmount").sum("agent_redeem_fee").as("agentFee")
              ).withOptions(Aggregation.newAggregationOptions().allowDiskUse(true).build()); 
            AggregationResults<BasicDBObject> outputTypeCount = moneySupportOrderDao.aggregate(aggregation, BasicDBObject.class);

 

參考:《學習MongoDB,在java中使用MongoTemplate聚合操作MongoDB

附帶官方文檔:https://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#mongo.aggregation

參考網站:

https://blog.csdn.net/ruoguan_jishou/article/details/79289369(聚合操作示例)

https://blog.csdn.net/qq_33556185/article/details/53099085(聚合操作分頁)

http://huangyongxing310.iteye.com/blog/2342307(超多示例)

https://www.cnblogs.com/nixi8/p/4856746.html(高級查詢:聚合操作之基礎)

http://shift-alt-ctrl.iteye.com/blog/2259216(  Aggregation超級詳細介紹)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM