1. 程式人生 > >二十三、mongodb聚合操作

二十三、mongodb聚合操作

1、mongodb的聚合是什麼

聚合(aggregate)是基於資料處理的聚合管道,每個文件通過一個由多個階段(stage)組成的管道,可以對每個階段的管道進行分組、過濾等功能,然後經過一系列的處理,輸出相應的結果。
在這裡插入圖片描述

db.集合名稱.aggregate({管道:{表示式}})

db.xiaoshuo.aggregate([{KaTeX parse error: Expected '}', got 'EOF' at end of input: match:{'age':{lt:40}}},{KaTeX parse error: Expected '}', got 'EOF' at end of input: group:{_id:'

gender’,counter:{$sum:1}}}])

2、mongodb的常用管道和表示式

2.1 常用管道命令

在mongodb中,⽂檔處理完畢後, 通過管道進⾏下⼀次處理 常用管道命令如下:

管道命令 含義
$group 將集合中的⽂檔分組, 可⽤於統計結果
$match 過濾資料, 只輸出符合條件的⽂檔
$project 修改輸⼊⽂檔的結構, 如重新命名、 增加、 刪除欄位、 建立計算結果
$sort 將輸⼊⽂檔排序後輸出
$limit 限制聚合管道返回的⽂檔數
$skip 跳過指定數量的⽂檔, 並返回餘下的⽂檔

2.2 常用表示式

表示式:處理輸⼊⽂檔並輸出 語法:表示式:’$列名’

管道命令 含義
$sum 計算總和, $sum:1 表示以⼀倍計數
$avg 計算平均值
$min 獲取最⼩值
$max 獲取最⼤值
$push 在結果⽂檔中插⼊值到⼀個數組中

3、管道命令之$group

3.1 按照某個欄位進行分組

$group是所有聚合命令中用的最多的一個命令,用來將集合中的文件分組,可用於統計結果。
使用示例如下

db.stu.aggregate(
    {$group:
        {
            _id:"$gender",
            counter:{$sum:1}
        }
    }
)

其中注意點:
db.db_name.aggregate是語法,所有的管道命令都需要寫在其中
_id 表示分組的依據,按照哪個欄位進行分組,需要使用$gender表示選擇這個欄位進行分組
$sum:1 表示把每條資料作為1進行統計,統計的是該分組下面資料的條數

3.2 group by null

當我們需要統計整個文件的時候,$group 的另一種用途就是把整個文件分為一組進行統計

使用例項如下:

db.stu.aggregate(
    {$group:
        {
            _id:null,
            counter:{$sum:1}
        }
    }
)

其中注意點:
_id:null 表示不指定分組的欄位,即統計整個文件,此時獲取的counter表示整個文件的個數

3.3 資料透視

正常情況在統計的不同性別的資料的時候,需要知道所有的name,需要逐條觀察,如果通過某種方式把所有的name放到一起,那麼此時就可以理解為資料透視

使用示例如下:

  • 統計不同性別的學生
db.stu.aggregate(
         {$group:
             {
                 _id:null,
                 name:{$push:"$name"}
             }
         }
     )
  • 使用$$ROOT可以將整個文件放入陣列中
 db.stu.aggregate(
         {$group:
             {
                 _id:null,
                 name:{$push:"$$ROOT"}
             }
         }
     )

3.4 動手

統計出每個hometown/age下的name的數量(同一個name只統計一次)
參考答案

db.stu.aggregate(
   {$group:{_id:{hometown:'$hometown',age:'$age',name:'$name'}}},
   {$group:{_id:{hometown:'$_id.hometown',age:'$_id.age'},count:{$sum:1}}})

分析:

  • 第一個管道的作用:排除了同一個地區和年齡,有相同名字的人
  • 第二個管道的作用:根據上一個分組,在進行分組資料統計

4、管道命令之$match

$match用於進行資料的過濾,是在能夠在聚合操作中使用的命令,和find區別在於$match 操作可以把結果交給下一個管道處理,而find不行。

使用示例如下:

  • 查詢年齡大於20的學生
 db.stu.aggregate(
         {$match:{age:{$gt:20}}
         )
  • 查詢年齡大於20的男女學生的人數
db.stu.aggregate(
         {$match:{age:{$gt:20}}},
         {$group:{_id:"$gender",counter:{$sum:1}}}
      )

5、管道命令之$project

$project用於修改文件的輸入輸出結構,例如重新命名,增加,刪除欄位

使用示例如下:

  • 查詢學生的年齡、姓名,僅輸出年齡姓名
db.stu.aggregate(
      {$project:{_id:0,name:1,age:1}}
      )
  • 查詢男女生人生,輸出人數
  db.stu.aggregate(
      {$group:{_id:"$gender",counter:{$sum:1}}}
      {$project:{_id:0,counter:1}}
      )

6、管道命令之$sort

$sort用於將輸入的文件排序後輸出

使用示例如下:

  • 查詢學生資訊,按照年齡升序
db.stu.aggregate({$sort:{age:1}})
  • 查詢男女人數,按照人數降序
 db.stu.aggregate(
       {$group:{_id:"$gender",counter:{$sum:1}}},
       {$sort:{counter:-1}}
   )

7、管道命令之$skip 和 $limit

$limit限制返回資料的條數
$skip 跳過指定的文件數,並返回剩下的文件數
同時使用時先使用skip在使用limit

使用示例如下:

  • 查詢2條學生資訊
  db.stu.aggregate(
         {$limit:2}
     )
  • 查詢從第四條開始的學生資訊
 db.stu.aggregate(
         {$skip:3}
     )
  • 統計男女生人數,按照人數升序,返回第二條資料
  db.stu.aggregate(
         {$group:{_id:'$gender', count:{$sum:1}}},
         {$sort:{count:1}},
         {$skip:1},
         {$limit:1}
     )