1. 程式人生 > >mongodb-aggregate(聚合函式)

mongodb-aggregate(聚合函式)

mongodb是有自己的mapreduce的,功能很強大,效能也還好,完成了基本上所有的關係型資料庫可以完成的統計工作;但是後來mongodb出現了聚合函式,嘗試著代替mapreduce,下面開始介紹聚合函式的使用:
aggregate() 方法

MongoDB中聚合的方法使用aggregate()。
語法

aggregate() 方法的基本語法格式如下所示:

db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)
db.collection.aggregate(pipeline, options);

pipeline Array

與mysql中的欄位對比說明

project10findaggregate使===>,select,select,aggregate,project是取出哪些資料進入下一個階段管道操作,真正的最終資料返回還是在group等操作中;

$match # 放在group前相當於where使用,放在group後面相當於having使用
match可以用於某個field對應多個value時的查詢 match和in搭配使用。

sort # 排序1升-1降 sort一般放在group後,也就是說得到結果後再排序,如果先排序再分組沒什麼意義;

limit # 相當於limit m,不能設定偏移量
$skip # 跳過第幾個文件
limit和skip搭配使用相當於關係型資料庫的分頁功能;但是skip在資料量比較大的時候,會拖慢效能,後面的文件我會繼續介紹,怎麼合理的使用(自己欠下的,哈哈)

unwind # 把文件中的陣列元素開啟,並形成多個文件,一般用於查詢內嵌陣列的時候使用,可以獲取到內嵌陣列文件的每一個值;  
參考Example1
group: { _id: <expression>, <field1>: { <accumulator1> : <expression1> }, ... # 按什麼欄位分組,注意所有欄位名前面都要加,

mongodb的是普通常量,其中accumulator又包括以下幾個操作符

sum,avg,first,last,max,min,push,addToSet

如果group by null就是 count(*)的效果

db.test.aggregate({_id:null,sum:{“sum”:1}}) ==select c  
ount(*)from table  
如果想實現針對某一列求和,而此時卻沒  
有比較好的的分組欄位,此時可以使用:  db.test.aggregate({_id:null,sum:{“
sum":"$field”}})
例項

集合中的資料如下:
{
_id: ObjectId(7df78ad8902c)
title: ‘MongoDB Overview’,
description: ‘MongoDB is no sql database’,
by_user: ‘w3cschool.cc’,
url: ‘http://www.w3cschool.cc‘,
tags: [‘mongodb’, ‘database’, ‘NoSQL’],
likes: 100
},
{
_id: ObjectId(7df78ad8902d)
title: ‘NoSQL Overview’,
description: ‘No sql database is very fast’,
by_user: ‘w3cschool.cc’,
url: ‘http://www.w3cschool.cc‘,
tags: [‘mongodb’, ‘database’, ‘NoSQL’],
likes: 10
},
{
_id: ObjectId(7df78ad8902e)
title: ‘Neo4j Overview’,
description: ‘Neo4j is no sql database’,
by_user: ‘Neo4j’,
url: ‘http://www.neo4j.com‘,
tags: [‘neo4j’, ‘database’, ‘NoSQL’],
likes: 750
},
現在我們通過以上集合計算每個作者所寫的文章數,使用aggregate()計算結果如下:

db.mycol.aggregate([{group : {_id : "by_user", num_tutorial : {$sum : 1}}}])
{
“result” : [
{
“_id” : “w3cschool.cc”,
“num_tutorial” : 2
},
{
“_id” : “Neo4j”,
“num_tutorial” : 1
}
],
“ok” : 1
}

以上例項類似sql語句: select by_user, count(*) from mycol group by by_user
在上面的例子中,我們通過欄位by_user欄位對資料進行分組,並計算by_user欄位相同值的總和。下表展示了一些聚合的表示式:
表示式 描述 例項
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”}}}])