鍍金池/ 教程/ 數(shù)據(jù)庫/ 聚合
更新文檔
GridFS
Rockmongo 管理工具
Map Reduce
Java
創(chuàng)建備份
數(shù)據(jù)模型
創(chuàng)建數(shù)據(jù)庫
映射
查詢文檔
索引限制
ObjectId
刪除文檔
數(shù)據(jù)類型
高級(jí)索引
索引
優(yōu)勢
記錄排序
查詢分析
插入文檔
刪除集合
全文檢索
創(chuàng)建集合
概述
數(shù)據(jù)庫引用
覆蓋索引查詢
安裝環(huán)境
PHP
刪除數(shù)據(jù)庫
固定集合
關(guān)系
聚合
自動(dòng)增長
復(fù)制
限制記錄
部署
分片
正則表達(dá)式
原子操作

聚合

聚合操作能夠處理數(shù)據(jù)記錄并返回計(jì)算結(jié)果。聚合操作能將多個(gè)文檔中的值組合起來,對(duì)成組數(shù)據(jù)執(zhí)行各種操作,返回單一的結(jié)果。它相當(dāng)于 SQL 中的 count(*) 組合 group by。

aggregate() 方法

對(duì)于 MongoDB 中的聚合操作,應(yīng)該使用 aggregate() 方法。

語法格式

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

>db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)

范例

假如某個(gè)集合包含下列數(shù)據(jù):

{
   _id: ObjectId(7df78ad8902c)
   title: 'MongoDB Overview', 
   description: 'MongoDB is no sql database',
   by_user: 'tutorials point',
   url: 'http://www.tutorialspoint.com',
   tags: ['mongodb', 'database', 'NoSQL'],
   likes: 100
},
{
   _id: ObjectId(7df78ad8902d)
   title: 'NoSQL Overview', 
   description: 'No sql database is very fast',
   by_user: 'tutorials point',
   url: 'http://www.tutorialspoint.com',
   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
},

假如想從上述集合中,歸納出一個(gè)列表,以顯示每個(gè)用戶寫的教程數(shù)量,需要像下面這樣使用 aggregate() 方法:

> db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : 1}}}])
{
   "result" : [
      {
         "_id" : "tutorials point",
         "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,就遞增之前的合計(jì)值。下面是聚合表達(dá)式列表。

表達(dá)式 描述 范例
$sum 對(duì)集合中所有文檔的定義值進(jìn)行加和操作 db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$sum : "$likes"}}}])
$avg 對(duì)集合中所有文檔的定義值進(jìn)行平均值 db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$avg : "$likes"}}}])
$min 計(jì)算集合中所有文檔的對(duì)應(yīng)值中的最小值 db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$min : "$likes"}}}])
$max 計(jì)算集合中所有文檔的對(duì)應(yīng)值中的最大值 db.mycol.aggregate([{$group : {_id : "$by_user", num_tutorial : {$max : "$likes"}}}])
$push 將值插入到一個(gè)結(jié)果文檔的數(shù)組中 db.mycol.aggregate([{$group : {_id : "$by_user", url : {$push: "$url"}}}])
$addToSet 將值插入到一個(gè)結(jié)果文檔的數(shù)組中,但不進(jìn)行復(fù)制 db.mycol.aggregate([{$group : {_id : "$by_user", url : {$addToSet : "$url"}}}])
$first 根據(jù)成組方式,從源文檔中獲取第一個(gè)文檔。但只有對(duì)之前應(yīng)用過 $sort 管道操作符的結(jié)果才有意義。 db.mycol.aggregate([{$group : {_id : "$by_user", first_url : {$first : "$url"}}}])
$last 根據(jù)成組方式,從源文檔中獲取最后一個(gè)文檔。但只有對(duì)之前進(jìn)行過 $sort 管道操作符的結(jié)果才有意義。 db.mycol.aggregate([{$group : {_id : "$by_user", last_url : {$last : "$url"}}}])

管道的概念

在 UNIX 命令 Shell 中,管道(pipeline)概念指的是能夠在一些輸入上執(zhí)行一個(gè)操作,然后將輸出結(jié)果用作下一個(gè)命令的輸入。MongoDB 的聚合架構(gòu)也支持這種概念。管道中有很多階段(stage),在每一階段中,管道操作符都會(huì)將一組文檔作為輸入,產(chǎn)生一個(gè)結(jié)果文檔(或者管道終點(diǎn)所得到的最終 JSON 格式的文檔),然后再將其用在下一階段。

聚合架構(gòu)中可能采取的管道操作符有:

  • $project 用來選取集合中一些特定字段。
  • $match 過濾操作。減少用作下一階段輸入的文檔的數(shù)量。
  • $group 如上所述,執(zhí)行真正的聚合操作。
  • $sort 對(duì)文檔進(jìn)行排序。
  • $skip 在一組文檔中,跳過指定數(shù)量的文檔。
  • $limit 將查看文檔的數(shù)目限制為從當(dāng)前位置處開始的指定數(shù)目。
  • $unwind 解開使用數(shù)組的文檔。當(dāng)使用數(shù)組時(shí),數(shù)據(jù)處于預(yù)連接狀態(tài),通過該操作,數(shù)據(jù)重新回歸為各個(gè)單獨(dú)的文檔的狀態(tài)。利用該階段性操作可增加下一階段性操作的文檔數(shù)量。
上一篇:原子操作下一篇:自動(dòng)增長