二、mongodb数据库系列——聚合操作 索引操作 权限管理
一、mongodb的聚合操作
學(xué)習(xí)目標(biāo)
1 mongodb的聚合是什么
聚合(aggregate)是基于數(shù)據(jù)處理的聚合管道,每個(gè)文檔通過一個(gè)由多個(gè)階段(stage)組成的管道,可以對(duì)每個(gè)階段的管道進(jìn)行分組、過濾等功能,然后經(jīng)過一系列的處理,輸出相應(yīng)的結(jié)果。
語法:db.集合名稱.aggregate({管道:{表達(dá)式}})
2 mongodb的常用管道和表達(dá)式
知識(shí)點(diǎn):
- 掌握mongodb中管道的語法
- 掌握mongodb中管道命令
2.1 常用管道命令
在mongodb中,?檔處理完畢后, 通過管道進(jìn)?下?次處理
常用管道命令如下:
- $group: 將集合中的?檔分組, 可?于統(tǒng)計(jì)結(jié)果
- $match: 過濾數(shù)據(jù), 只輸出符合條件的?檔
- $project: 修改輸??檔的結(jié)構(gòu), 如重命名、 增加、 刪除字段、 創(chuàng)建計(jì)算結(jié)果
- $sort: 將輸??檔排序后輸出
- $limit: 限制聚合管道返回的?檔數(shù)
- $skip: 跳過指定數(shù)量的?檔, 并返回余下的?檔
2.2 常用表達(dá)式
表達(dá)式:處理輸??檔并輸出
語法:表達(dá)式:'$列名'
常?表達(dá)式:
- $sum: 計(jì)算總和, $sum:1 表示以?倍計(jì)數(shù)
- $avg: 計(jì)算平均值
- $min: 獲取最?值
- $max: 獲取最?值
- $push: 在結(jié)果?檔中插?值到?個(gè)數(shù)組中
3 管道命令之$group
3.1 按照某個(gè)字段進(jìn)行分組
$group是所有聚合命令中用的最多的一個(gè)命令,用來將集合中的文檔分組,可用于統(tǒng)計(jì)結(jié)果
使用示例如下
db.stu.aggregate({$group:{_id:"$gender",counter:{$sum:1}}} )其中注意點(diǎn):
- db.db_name.aggregate是語法,所有的管道命令都需要寫在其中
- _id 表示分組的依據(jù),按照哪個(gè)字段進(jìn)行分組,需要使用$gender表示選擇這個(gè)字段進(jìn)行分組
- $sum:1 表示把每條數(shù)據(jù)作為1進(jìn)行統(tǒng)計(jì),統(tǒng)計(jì)的是該分組下面數(shù)據(jù)的條數(shù)
3.2 group by null
當(dāng)我們需要統(tǒng)計(jì)整個(gè)文檔的時(shí)候,$group 的另一種用途就是把整個(gè)文檔分為一組進(jìn)行統(tǒng)計(jì)
使用實(shí)例如下:
db.stu.aggregate({$group:{_id:null,counter:{$sum:1}}} )其中注意點(diǎn):
- _id:null 表示不指定分組的字段,即統(tǒng)計(jì)整個(gè)文檔,此時(shí)獲取的counter表示整個(gè)文檔的個(gè)數(shù)
3.3 數(shù)據(jù)透視
正常情況在統(tǒng)計(jì)的不同性別的數(shù)據(jù)的時(shí)候,需要知道所有的name,需要逐條觀察,如果通過某種方式把所有的name放到一起,那么此時(shí)就可以理解為數(shù)據(jù)透視
使用示例如下:
統(tǒng)計(jì)不同性別的學(xué)生
db.stu.aggregate({$group:{_id:null,name:{$push:"$name"}}} )使用$$ROOT可以將整個(gè)文檔放入數(shù)組中
db.stu.aggregate({$group:{_id:null,name:{$push:"$$ROOT"}}} )3.4 動(dòng)手
對(duì)于如下數(shù)據(jù),需要統(tǒng)計(jì)出每個(gè)country/province下的userid的數(shù)量(同一個(gè)userid只統(tǒng)計(jì)一次)
{ "country" : "china", "province" : "sh", "userid" : "a" } { "country" : "china", "province" : "sh", "userid" : "b" } { "country" : "china", "province" : "sh", "userid" : "a" } { "country" : "china", "province" : "sh", "userid" : "c" } { "country" : "china", "province" : "bj", "userid" : "da" } { "country" : "china", "province" : "bj", "userid" : "fa" }參考答案
db.tv3.aggregate({$group:{_id:{country:'$country',province:'$province',userid:'$userid'}}},{$group:{_id:{country:'$_id.country',province:'$_id.province'},count:{$sum:1}}}4 管道命令之$match
$match用于進(jìn)行數(shù)據(jù)的過濾,是在能夠在聚合操作中使用的命令,和find區(qū)別在于$match 操作可以把結(jié)果交給下一個(gè)管道處理,而find不行
先匹配出符合條件age為18的所有記錄,然后把這些匹配到的記錄按照性別gender進(jìn)行分組,并且把分好組的后,每個(gè)組中存在的成員的name名字顯示出來:
- 第一個(gè)管道為:match,即{$match:{age:18}}
- 第二個(gè)管道為:group,即{$group:{_id:"$gender",name:{$push:"$name"}}}
- 第一個(gè)管道得到的結(jié)果 作為 第二個(gè)管道的輸入內(nèi)容
使用示例如下:
查詢年齡大于20的學(xué)生
db.stu.aggregate({$match:{age:{$gt:20}})查詢年齡大于20的男女學(xué)生的人數(shù)
db.stu.aggregate({$match:{age:{$gt:20}}{$group:{_id:"$gender",counter:{$sum:1}}})5 管道命令之$project
$project用于修改文檔的輸入輸出結(jié)構(gòu),例如重命名,增加,刪除字段
使用示例如下:
查詢學(xué)生的年齡、姓名,僅輸出年齡姓名
db.stu.aggregate({$project:{_id:0,name:1,age:1}})查詢男女生人生,輸出人數(shù)
db.stu.aggregate({$group:{_id:"$gender",counter:{$sum:1}}}{$project:{_id:0,counter:1}})
5.1 動(dòng)手練習(xí)
對(duì)于如下數(shù)據(jù):統(tǒng)計(jì)出每個(gè)country/province下的userid的數(shù)量(同一個(gè)userid只統(tǒng)計(jì)一次),結(jié)果中的字段為{country:"",province:"",counter:"*"}
{ "country" : "china", "province" : "sh", "userid" : "a" } { "country" : "china", "province" : "sh", "userid" : "b" } { "country" : "china", "province" : "sh", "userid" : "a" } { "country" : "china", "province" : "sh", "userid" : "c" } { "country" : "china", "province" : "bj", "userid" : "da" } { "country" : "china", "province" : "bj", "userid" : "fa" }參考答案
db.tv3.aggregate({$group:{_id:{country:'$country',province:'$province',userid:'$userid'}}},{$group:{_id:{country:'$_id.country',province:'$_id.province'},count:{$sum:1}}},{$project:{_id:0,country:'$_id.country',province:'$_id.province',counter:'$count'}})6 管道命令之$sort
$sort用于將輸入的文檔排序后輸出
使用示例如下:
查詢學(xué)生信息,按照年齡升序
db.stu.aggregate({$sort:{age:1}})查詢男女人數(shù),按照人數(shù)降序
db.stu.aggregate({$group:{_id:"$gender",counter:{$sum:1}}},{$sort:{counter:-1}} )7 管道命令之$skip 和 $limit
- $limit限制返回?cái)?shù)據(jù)的條數(shù)
- $skip 跳過指定的文檔數(shù),并返回剩下的文檔數(shù)
- 同時(shí)使用時(shí)先使用skip在使用limit
使用示例如下:
查詢2條學(xué)生信息
db.stu.aggregate({$limit:2} )查詢從第三條開始的學(xué)生信息
db.stu.aggregate({$skip:3} )統(tǒng)計(jì)男女生人數(shù),按照人數(shù)升序,返回第二條數(shù)據(jù)
db.stu.aggregate({$group:{_id:"$gender",counter:{$sum:1}}},{$sort:{counter:-1}},{$skip:1},{$limit:1} )管道命令:拆分
8 小結(jié)
二、Mongodb的索引操作
學(xué)習(xí)目標(biāo)
1. 為什么mongdb需要?jiǎng)?chuàng)建索引
- 加快查詢速度
- 進(jìn)行數(shù)據(jù)的去重
2. mongodb創(chuàng)建簡(jiǎn)單的索引方法
- 語法:db.集合名.ensureIndex({屬性:1}),1表示升序, -1表示降序
3. 創(chuàng)建索引前后查詢速度對(duì)比
測(cè)試:插入10萬條數(shù)據(jù)到數(shù)據(jù)庫中
插入數(shù)據(jù):
for(i=0;i<100000;i++){db.t1.insert({name:'test'+i,age:i})}創(chuàng)建索引前:
db.t1.find({name:'test10000'}) db.t1.find({name:'test10000'}).explain('executionStats') # 顯示查詢操作的詳細(xì)信息創(chuàng)建索引:
db.t1.ensureIndex({name:1})創(chuàng)建索引后:
db.t1.find({name:'test10000'}).explain('executionStats')前后速度對(duì)比
4. 索引的查看
默認(rèn)情況下_id是集合的索引
查看方式:db.集合名.getIndexes()
5. 刪除索引
語法:db.集合名.dropIndex({'索引名稱':1})
db.t1.dropIndex({name:1}) db.t1.getIndexes()6. mongodb創(chuàng)建唯一索引
在默認(rèn)情況下mongdb的索引域的值是可以相同的,創(chuàng)建唯一索引之后,數(shù)據(jù)庫會(huì)在插入數(shù)據(jù)的時(shí)候檢查創(chuàng)建索引域的值是否存在,如果存在則不會(huì)插入該條數(shù)據(jù),但是創(chuàng)建索引僅僅能夠提高查詢速度,同時(shí)降低數(shù)據(jù)庫的插入速度。
6.1 添加唯一索引的語法:
db.集合名.ensureIndex({"字段名":1}, {"unique":true})6.2 利用唯一索引進(jìn)行數(shù)據(jù)去重
根據(jù)唯一索引指定的字段的值,如果相同,則無法插入數(shù)據(jù)
db.t1.ensureIndex({"name":1}, {"unique":true}) db.t1.insert({name: 'test10000'})7. 建立復(fù)合索引
在進(jìn)行數(shù)據(jù)去重的時(shí)候,可能用一個(gè)域來保證數(shù)據(jù)的唯一性,這個(gè)時(shí)候可以考慮建立復(fù)合索引來實(shí)現(xiàn)。
例如:抓全貼吧信息,如果把帖子的名字作為唯一索引對(duì)數(shù)據(jù)進(jìn)行去重是不可取的,因?yàn)榭赡苡泻芏嗵用窒嗤?/p>
建立復(fù)合索引的語法:db.collection_name.ensureIndex({字段1:1,字段2:1})
8. 建立索引注意點(diǎn)
-
根據(jù)需要選擇是否需要建立唯一索引
-
索引字段是升序還是降序在單個(gè)索引的情況下不影響查詢效率,但是帶復(fù)合索引的條件下會(huì)有影響
-
數(shù)據(jù)量巨大并且數(shù)據(jù)庫的讀出操作非常頻繁的時(shí)候才需要?jiǎng)?chuàng)建索引,如果寫入操作非常頻繁,創(chuàng)建索引會(huì)影響寫入速度
例如:在進(jìn)行查詢的時(shí)候如果字段1需要升序的方式排序輸出,字段2需要降序的方式排序輸出,那么此時(shí)復(fù)合索引的建立需要把字段1設(shè)置為1,字段2設(shè)置為-1
課后思考
數(shù)據(jù)庫為什么要做讀寫分離(讀寫分離的意義)?
小結(jié)
三、Mongodb的權(quán)限管理
學(xué)習(xí)目標(biāo)
1.了解 mongodb的權(quán)限管理
1. 為什么要進(jìn)行權(quán)限管理的設(shè)置
剛安裝完畢的mongodb默認(rèn)不使用權(quán)限認(rèn)證方式啟動(dòng),與MySQL不同,mongodb在安裝的時(shí)候并沒有設(shè)置權(quán)限,然而公網(wǎng)運(yùn)行系統(tǒng)需要設(shè)置權(quán)限以保證數(shù)據(jù)安全,所以我們要學(xué)習(xí)mongodb的權(quán)限管理
2. mongodb的權(quán)限管理方案
- MongoDB是沒有默認(rèn)管理員賬號(hào),所以要先添加管理員賬號(hào),并且mongodb服務(wù)器需要在運(yùn)行的時(shí)候開啟驗(yàn)證模式
- 用戶只能在用戶所在數(shù)據(jù)庫登錄(創(chuàng)建用戶的數(shù)據(jù)庫),包括管理員賬號(hào)。
- 管理員可以管理所有數(shù)據(jù)庫,但是不能直接管理其他數(shù)據(jù)庫,要先認(rèn)證后才可以。
3. mongodb超級(jí)管理員賬號(hào)的創(chuàng)建
3.1 創(chuàng)建超級(jí)用戶
進(jìn)入mongo shell
sudo mongod使用admin數(shù)據(jù)庫(超級(jí)管理員賬號(hào)必須創(chuàng)建在該數(shù)據(jù)庫上)
use admin創(chuàng)建超級(jí)用戶
db.createUser({"user":"python","pwd":"python","roles":["root"]})創(chuàng)建成功會(huì)顯示如下信息
Successfully added user: { "user" : "python", "roles" : [ "root" ] }退出mongo shell
exit3.2 以權(quán)限認(rèn)證的方式啟動(dòng)mongodb數(shù)據(jù)庫
sudo mongod --auth啟動(dòng)之后在啟動(dòng)信息中會(huì)有如下信息,說明mongodb以權(quán)限認(rèn)證的方式啟動(dòng)成功
[initandlisten] options: { security: { authorization: "enabled" } }3.3 登錄驗(yàn)證
此時(shí)再使用數(shù)據(jù)庫各命令的時(shí)候會(huì)報(bào)權(quán)限錯(cuò)誤,需要認(rèn)證才能執(zhí)行相應(yīng)操作、
use admin db.auth('python','python')- python用戶是創(chuàng)建在admin數(shù)據(jù)庫上的所以必須來到admin數(shù)據(jù)庫上進(jìn)行認(rèn)證
- 認(rèn)證成功會(huì)返回1,失敗返回0
4. 創(chuàng)建普通用戶
4.1 在使用的數(shù)據(jù)庫上創(chuàng)建普通用戶
1.選擇需要?jiǎng)?chuàng)建用戶的數(shù)據(jù)庫
use test14.2 在admin用戶數(shù)據(jù)庫上創(chuàng)建普通用戶
use admin db.createUser({"user":"python1", "pwd":"python1", roles:[{"role":"read","db":"dbname1"},{"role":"readWrite","db":"dbname2"} ]})在admin上創(chuàng)建python1用戶,python1用戶的權(quán)限有兩個(gè),一個(gè)再dbname1上的只讀,另一個(gè)是在dbname2上的讀寫
5. 查看創(chuàng)建的用戶
show users {"_id" : "admin.python","user" : "python","db" : "admin","roles" : [{"role" : "root","db" : "admin"}] }6. 刪除用戶
6.1 進(jìn)入賬號(hào)數(shù)據(jù)所在的數(shù)據(jù)庫
use db_name6.2 刪除用戶
db.dropUser('python')小結(jié)
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)
總結(jié)
以上是生活随笔為你收集整理的二、mongodb数据库系列——聚合操作 索引操作 权限管理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mac最好用的markdown_「建议收
- 下一篇: 十三、PHP框架Laravel学习笔记—