mongodb常用的兩種group方法,以及對結果排序
mongodb作為no-sql資料庫的典型代表,擁有著儲存海量資料的效能,在插入資料和查詢資料方便也有著相對於其他關係型資料庫明顯的優勢,最近學習了mongodb,發現mongodb中沒有mysql中的group關鍵字,但是同樣的以其他形式實現了對應的功能,下面總結了兩種mongdb常用的group方法,介紹給大家。
第一種方法是利用管道來進行,管道是由一系列的功能節點組成的,當文件從一個操作節點流向下一個操作節點的時候,每個操作節點就會對文件做出相應的操作。主要是有兩個功能,1,進行過濾,2,變換,也就是改變文件的輸出形式。
主要是通過
Aggreagtion管道操作符主要有:
match:用於對文件集合進行篩選,之後就可以在篩選得到的文件子集中做聚合。
project:管道的投射,可以從子文件中提取欄位,可以重新命名欄位
group:將文件根據特定的欄位的不同值進行分組
unwind:可以將陣列中的每一個值拆分為單獨的文件。
這裡舉一個mongodb權威指南上的例子
一篇擁有多條評論的部落格,利用unwind可以將每條評論都拆分為一個獨立的文件。
sort:根據任何欄位或者是多個欄位可以進行排序,如果是大量的文件需要排序,建議在管道的第一階段排序。
limit:接受一個數字n,返回結果集的前n個文件。
skip:接受一個數字n,丟棄結果集中的前n個文件,將剩餘文件作為結果返回。
下面是利用管道的group使用以及mapreduce在mongodb中的使用
Mongo m = new Mongo(“localhost”:27017);
DB db = m.getDB(“test”);//test為資料庫的名稱
DBCollection coll = db.getCollection(“test”)//test為集合名稱
//下面則就行構造管道中操作節點的操作符,主要用到的物件就是DBObject
DBObject match = new BasicDBObject("$match", new BasicDBObject("欄位名", "欄位值"));//限定查詢條件,相當於Query,規定某個欄位的值進行groupby
DBObject groupFields = new BasicDBObject(“_id”,”$欄位名”);//也就是說groupby這個欄位名
groupFields.put(“SumElectricty”,new BasicDBObject(“$sum”,”$欄位名”));//對這個欄位名的值進行求和,並且把這個和值生成一個名為SumElectricty的欄位。
DBObject group = new BasicDBObject(“$group”,groupFields);
//放到管道中將這些節點運算子運算起來
AggregationOutput output = coll.aggregate(match,group);
//AggregationOutput 類有getCommandResult(),返回執行結果,結果是CommandResult,可以檢視到。
mapreduce在mongodb中同樣可以聚類,採用的是javascript作為查詢語言,但是不得不承認的是,mapreduce非常慢,一般是不會用在實時的資料分析中的。這裡做的是以在一個時間段內,對mac_id進行聚合,求欄位electrity_quantity的和,並且排序顯示出前n名。
起初我用的是比較笨的方法,並沒有注意到query自身就可以進行排序並且還可以發揮前n個最大的結果集的能力。下面是這兩個方法的程式碼。。
public Map groupbyId(Date d1,Date d2){
double total = 0;
String reduce = "function(doc, aggr){" +
" aggr.total += doc.electric_quantity;" +
" }"; //doc代表的是當前的文件,而aggr為之前所處理的文件的集合
Query query = new Query();
Criteria criteria = Criteria.where("record_time").gte(d1);//欄位record_time的值大於等於d1
criteria.and("record_time").lte(d2);//record_time的值小於等於d2
query.addCriteria(criteria);//將條件插入到查詢中
DBCollection coll = mongoTemplate.getCollection("smartsocketer");//獲得名為smartsocketer的集合
DBObject result = coll.group(new BasicDBObject("mac_id", 1), query.getQueryObject(), new BasicDBObject("total", total), reduce);//groupby mac_id,在剛剛的查詢條件下,執行reduce函式,並且將獲得值放在名為total的欄位中
Map<String,BasicDBObject> map = result.toMap(); //將結果轉換為k-v的map
return map;
}
public List<BasicDBObject> sortMapByValue(Map<String, BasicDBObject> oriMap,int n) {
List<BasicDBObject> mappingList = new ArrayList<BasicDBObject>();
if (oriMap != null && !oriMap.isEmpty()) {
Iterator it = oriMap.entrySet().iterator();//獲得是文件
while(it.hasNext()){
Map.Entry<String,BasicDBObject> map = (Entry<String, BasicDBObject>) it.next();
BasicDBObject dbob = map.getValue();
dbob.entrySet();
mappingList.add(dbob);
}
Collections.sort(mappingList, new Comparator<BasicDBObject>() {
public int compare(BasicDBObject entry1, BasicDBObject entry2) {
double value1 = 0, value2 = 0;
try {
value1 = Double.parseDouble(entry1.getString("total"));
value2 = Double.parseDouble(entry2.getString("total"));
} catch (NumberFormatException e) {
value1 = 0;
value2 = 0;
}
if(value1-value2<0)
{
return 1;
}
if(value1-value2>0)
{
return -1;
}
return 0;
}
});
}
return mappingList.subList(0, n); //擷取mappingList,而mappingList是排好序的list,直接擷取就可以獲得top;
}
剛開始一直在困擾的是我在進行map排序的時候,實際上將map.entry放到list中去然後定義比較器比較entry的value就可以了,後來我發現group後發揮的map是下面這種形式的。
{1,{01,23.5}}
也就是說map的key值完全是索引,是自動生成的,並不是我所想到的mac_id欄位值。
實際上就是BasicDBObject,因此直接定義這個物件的比較器就可以了。
當然更為簡單的方法是利用query來做,在查詢的時候就
query.with(new Sort(Direction.DESC, “欄位名”));
上面就是兩種方法,還有很多待補充的地方。挖坑第一天,一定要堅持下去>:<
相關文章
- Treeset的兩種排序方法排序
- SQL Server對組合查詢結果排序方法SQLServer排序
- Java中三種常用的排序方法Java排序
- mysql group by 取想要的結果MySql
- ORDER對查詢結果進行排序排序
- 基於桶的排序之基數排序以及排序方法總結排序
- 九種常用排序的效能分析總結 [zhuan]排序
- ISNULL 兩種寫法,得到兩種結果,返回空記錄與nullNull
- 大資料MongoDB之mgo驅動如何對查詢結果進行排序(正序逆序多欄位排序)?大資料MongoDB排序
- MongoDB資料庫的兩種正確停庫方法MongoDB資料庫
- 做實驗驗證MongoDB分頁的兩種方法MongoDB
- 【Mongodb】 replica set 兩種新增節點方法的日誌分析MongoDB
- 小議分析函式中排序對結果的影響(二)函式排序
- 小議分析函式中排序對結果的影響(一)函式排序
- Mongodb 常用的查詢方法MongoDB
- py連線mysql常用驅動的兩種對比MySql
- 遍歷物件鍵值對的兩種方法物件
- 六種排序演算法的JavaScript實現以及總結排序演算法JavaScript
- ts - 兩種方法實現忽略大小寫的字串排序字串排序
- python list排序的兩種方法及例項講解Python排序
- Oracle Spool的用法小結以及兩種方法的比較----------匯出記錄到文字Oracle
- 常用的兩種加密原理加密
- 幾種常用的排序程式碼排序
- Python保留兩位小數五種常用的方法!Python
- Python遍歷資料夾常用的兩種方法!Python
- Java連線oracle資料庫的兩種常用方法JavaOracle資料庫
- 兩種檢視oracle表結構的方法Oracle
- 建立連結串列兩種方法的區別
- mongodb 對記憶體的嚴重佔用以及解決方法MongoDB記憶體
- MongoDB對記憶體的嚴重佔用以及解決方法MongoDB記憶體
- MySQL order by 排序結果不正確MySql排序
- JS常用判斷空對像的幾種方法JS
- 幾種常用的排序演算法排序演算法
- NC65對單表單據查詢的結果進行排序排序
- 求陣列長度的兩種方法,以及區別(strlen sizeof)陣列
- C#常用8種排序演算法實現以及原理簡介C#排序演算法
- 三種快速排序演算法以及快速排序的優化排序演算法優化
- MONGODB 最近測試結果的簡單記錄MongoDB