MongoDB管道
今天和大家分享mongodb中管道
,老規矩貼上官方文件
我們從聚合慢慢引入管道的概念
mongo中常見的聚合有count,distinct,group,mapReduce
我們先建立好測試資料,檢視一下
> db.student.find().pretty() { "_id" : 1, "name" : "tom", "age" : 20, "scores" : 98 } { "_id" : 2, "name" : "jack", "age" : 21, "scores" : 89 } { "_id" : 3, "name" : "lucy", "age" : 19, "scores" : 91 } { "_id" : 4, "name" : "luna", "age" : 21, "scores" : 91 }
下面來介紹個方法的使用
1.count統計文件數量
> db.student.count()//統計文件數量 4 > db.student.count({"age": {$gte: 20}})//統計年齡大於等於20的文件數量 3
2.countDocuments
mongo4.0以上的版本已經不推薦使用count
了,取而代之的是countDocuments
> db.student.countDocuments({"age": {$gte: 20}}) 3
3.distinct獲取指定欄位的值的分佈(去重)
> db.student.distinct("scores") [ 98, 89, 91 ]
4.aggregate(管道)替代group
,老闆本mongo是有直接的命令group
來分組的
官方原文
DEPRECATED SINCE VERSION 3.4
Mongodb 3.4 deprecates the
group
command. Use
db.collection.aggregate()
with the
$group
stage or
db.collection.mapReduce()
instead.
mongodb3.4版本廢棄了group
命令,取而代之的是db.collection.aggregate
和db.collection.mapReduce
> db.student.aggregate([ {$group: {_id: "$scores", person_num : {$sum: "$scores"}}} ]) { "_id" : 91, "person_num" : 182 } { "_id" : 89, "person_num" : 89 } { "_id" : 98, "person_num" : 98 }
類似於mysql的select scores, count(*) as person_num from student group by scores
$sum
後面的是什麼意思呢,對scores欄位求和
> db.student.aggregate([ {$match: {"name": {$in: ["tom", "jack", "luna"]}}}, {$group: {_id: "$scores", person_num : {$sum: 1}}} ]) { "_id" : 91, "person_num" : 1 } { "_id" : 89, "person_num" : 1 } { "_id" : 98, "person_num" : 1 }
這裡就是一個典型的管道使用情況了, 以上命令執行了兩步,在一個管道里面執行
name
既然說到了分組group
我就順便再講幾個聚合方法吧
根據年齡分組求平均值例項
> db.student.find() { "_id" : 1, "name" : "tom", "age" : 20, "scores" : 98 } { "_id" : 2, "name" : "jack", "age" : 21, "scores" : 89 } { "_id" : 3, "name" : "lucy", "age" : 19, "scores" : 91 } { "_id" : 4, "name" : "luna", "age" : 21, "scores" : 91 } > db.student.aggregate([{$group : {_id: "$age", avg_scores: {$avg: "$scores"}}}]) { "_id" : 19, "avg_scores" : 91 } { "_id" : 21, "avg_scores" : 90 } { "_id" : 20, "avg_scores" : 98 }
根據分數分組,求組內最小的分數
> db.student.aggregate([{$group : {_id: "$scores", min_scores: {$min: "$age"}}}]) { "_id" : 91, "min_scores" : 19 } { "_id" : 89, "min_scores" : 21 } { "_id" : 98, "min_scores" : 20 }
對應的$max方法語法一直
總結:
表示式 | 描述 | 語法 |
---|---|---|
$sum | 計算總和 |
db.mycol.aggregate([{ |
$avg | 計算平均值 |
db.mycol.aggregate([{ |
$min | 獲取集合中所有文件對應值得最小值 |
db.mycol.aggregate([{ |
$max | 獲取集合中所有文件對應值得最大值 |
db.mycol.aggregate([{ |
$by_field
是分組的欄位,比如按年齡分組就改成$age
alias_name
是統計資料之後的一個別名,類似於mysql的as
$field
是聚合的欄位 比如按年齡分組後取分組中scores的最大值就把$field
改為$scores
管道中的排序
文件的排序也是要通過管道來實現的
> db.student.aggregate([{$sort : {age : 1}}]) { "_id" : 3, "name" : "lucy", "age" : 19, "scores" : 91 } { "_id" : 1, "name" : "tom", "age" : 20, "scores" : 98 } { "_id" : 2, "name" : "jack", "age" : 21, "scores" : 89 } { "_id" : 4, "name" : "luna", "age" : 21, "scores" : 91 }
官方原文
For the field or fields to sort by, set the sort order to1
or-1
to specify an ascending or descending sort respectively, as in the following example:
1是升序asc,-1是降序desc
最後說一下管道中的其它操作
-
$project
:修改輸入文件的結構。可以用來重新命名、增加或刪除域,也可以用於建立計算結果以及巢狀文件。 -
$match
:用於過濾資料,只輸出符合條件的文件。$match
使用MongoDB的標準查詢操作。 -
$limit
:用來限制MongoDB聚合管道返回的文件數。 -
$skip
:在聚合管道中跳過指定數量的文件,並返回餘下的文件。 -
$unwind
:將文件中的某一個數組型別欄位拆分成多條,每條包含陣列中的一個值。 -
$group
:將集合中的文件分組,可用於統計結果。 -
$sort
:將輸入文件排序後輸出。 -
$geoNear
:輸出接近某一地理位置的有序文件
本文寫的有點亂,希望看官不要見怪!!!