Mongodb聚合函數


 

插入 測試數據

復制代碼
for(var j=1;j<3;j++){    
for(var i=1;i<3;i++){    
  var person={
    Name:"jack"+i,
    Age:i,
    Address:["henan","wuhan"],
    Course:[
    {Name:"shuxue",Score:i},
    {Name:"wuli",Score:i}
    ]
  }
  db.DemoTest.Person.insert(person)     
}
}
復制代碼

 

Count

db.DemoTest.Person.count({Name:"jack1"})

返回數量

 

 distinct

db.DemoTest.Person.distinct("Name")

返回不重復的Name值。

 

 group

例子:按照Name分組,條件是Age大於46

復制代碼
db.DemoTest.Person.group({
    "key":{"Name":true}, -----分組的keky
    "initial":{"Person":[]},-------每組分享的一個”初始化函數“
    "$reduce":function(cur,prev){   ------這個函數的第一個參數是當前的文檔對象,第二個參數是上一次function操作的累計對象,第一次為initial中的{”person“:[]}。有多少個文檔, $reduce就會調用多少次

prev.Person.push(cur);
},
    "finalize":function(prev){   ---返回每組的數量     
      prev.count=prev.Person.length;  
    },
    "condition":{"Age":{"$lt":46}}   -----過濾條件
    })
復制代碼

返回結果如下:

  返回的json

 

 mapReduce

 mapReduce其實是一種編程模型,用在分布式計算中,其中有一個“map”函數,一個”reduce“函數。

   map:

          這個稱為映射函數,里面會調用emit(key,value),集合會按照你指定的key進行映射分組。

   reduce:

         這個稱為簡化函數,會對map分組后的數據進行分組簡化,注意:在reduce(key,value)中的key就是

      emit中的key,vlaue為emit分組后的emit(value)的集合,這里也就是很多{"count":1}的數組。

   mapReduce:

          這個就是最后執行的函數了,參數為map,reduce和一些可選參數。

 

在MongoDB存儲的文檔上執行聚合操作非常有用,這種方式的一個限制是聚合函數(比如,SUM、AVG、MIN、MAX)需要通過mapper和reducer函數來定制化實現。

MongoDB沒有原生態的用戶自定義函數(UDFs)支持。但是它允許使用db.system.js.save命令來創建並保存JavaScript函數,JavaScript函數可以在MapReduce中復用。

 

第一種統計方式--對應集合直接統計

1.在MongoDB javascript Shell中對Array對象進行了一些擴展,其中新增sum方法,以方便統計數據之用的。

復制代碼
Array.sum=function(arr){
if(arr.length == 0)
return null;
var s = arr[0];
for(var i = 1; i < arr.length; i++)
s += arr[i];
return s;
}
復制代碼

2.例子:按照名稱分組,統計每組年齡的和,條件是年齡小於2.

如果統計數量:var map = function(){ emit(this.Name, 1); }   其實是讓值永遠為1

var map = function(){ emit(this.Name, this.Age); }
var reduce = function( key, values ){ return Array.sum(values); }
var options = {query: { Age: {$lt: 2} }, out: { inline : 1 }}
db.Person.mapReduce(map,reduce,options)

結果如下

  結果json

 

分析一下:
1. map部分
作用:用於分組的。
emit(param1, param2)
param1:需要分組的字段,this.字段名。
param2:需要進行統計的字段,this.字段名。

2. reduce部分
作用:處理需要統計的字段
var reduce = function(key, values){
......統計字段處理
}
key: 指分組字段(emit的param1)對應的值
values:指需要統計的字段(emit的param2)值組成的數組

簡單介紹統計常用的方法:
* 對數值類型進行求和

1
2
3
4
<span style= "font-size: 16px;" > var  reduce = function (key, values){
return  Array.sum(values);
}
</span>

* 對字符串類型進行拼湊

1
2
3
<span style= "font-size: 16px;" > var  reduce = function (key, values){
return  values.join( ', ' );
}</span>

3. options部分
{ query: { age: {$lt: 25} }, out: "name_totals" }
query:先篩選符合條件的記錄出來,再進行分組統計。
out:將分組統計后的結果輸出到哪個集合當中。
默認情況下,out所指定的集合在數據庫斷開連接后再次打開時,依舊存在,並保留之前的所有記錄的。

4. 執行分組統計
>db.集合名.mapReduce( map, reduce, options )

 

第二種統計方式--命令統計

1.命令如下:

注意:out參數 out:"Person_Name" 代表會創建一個臨時表Person_Name 然后再從臨時表中查找,out:{inline:1} 代表直接顯示在當前命令執行的結果中

復制代碼
var map = function(){ emit(this.Name, this.Age); }
var reduce = function( key, values ){ return Array.sum(values); }
db.runCommand({
    mapreduce:"Person",
    map:map,
    reduce:reduce,
    out:"Person_Name",
    keeptemp: false,
    query: { Age:{ $lt: 2 }},
    sort:{ Name:1},
limit:3
})
復制代碼

 解析:
mapreduce:
分組統計的集合名
eg:
mapreduce: 'mythings'
不能寫成mapreduce: mythings,否則報異常:mythings is not defined

map,reduce :
同上,不做闡述

out :
將分組統計結果輸出到某個集合。
注意:不能缺省,必須指定名稱,否則報錯,報錯如下:
“exception: 'out' has to be a string or an object”

keeptemp :
是否保留臨時集合(指out指定的集合)
keeptemp:false時會在數據庫斷開連接后,MongoDB會移除該集合的所有記錄。而不是刪除。
keeptemp:true時即使數據庫斷開連接后,再次連接上,該臨時集合依舊保持之前所有記錄。
keeptemp默認值為true。

query :
篩選記錄后,再進行分組統計
eg:
query: { age:{ $lt: 25 }}

sort :
對分組統計的集合進行排序,也即先排序,后再執行分組統計的。
注意:這里的排序需要用到索引,必須先創建索引。

limit :

對分組統計的集合先進行限制返回記錄的條數,然后再去進行統計操作。注意:不要理解成對統計后的結果進行限制返回記錄條數。

verbose :
顯示時間統計信息,取值為true/false


免責聲明!

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



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