MongoDB基础知识总结
一、安裝
Linux:
? 命令安裝
? sudo apt install -y mongodb-org
? 源碼安裝
? 下載源碼——解壓——移動到/usr/local/目錄下——在shell的初始化腳本.bashrc中添加mongodb可執(zhí)行文件到環(huán)境變量path中。(在.bashrc文件的最后添加export PATH=/usr/local/mongodb/bin:$PATH)
二、簡單使用
默認端口:27017
默認配置文件的位置:/etc/mongodb.conf
默認日志的位置:/var/log/mongodb/mongodb.log
啟動方式:
? 本地測試方式啟動,只具有本地數(shù)據(jù)增刪改查的功能,主要是驗證數(shù)據(jù)庫是否能正常運行
? 生產(chǎn)環(huán)境啟動,具有完整的全部功能,服務(wù)器部署啟動
本地測試方式啟動:
? 啟動 sudo service mongodb start
? 停止 sudo service mongodb stop
? 重啟 sudo service mongodb restart
生產(chǎn)環(huán)境正式的啟動方式:
? sudo mongod 可選參數(shù)
? 只以sudo mongod 命令啟動時,默認將數(shù)據(jù)存放在了/data/db目錄下,需要手動創(chuàng)建
? 可選參數(shù):
? --dbpath=數(shù)據(jù)庫存放路徑(絕對路徑)
? --logpath=日志文件的存放路徑,重啟后日志會覆蓋原來的日志,不是追加寫入
? 在后面添加–append或者–logappend 可以設(shè)置日志的寫入形式為追加模式
? --fork或者-fork 在當(dāng)前進程下開啟新的子進程運行mongodb服務(wù),一旦開啟成功,父進程就會退出
? --auth 以權(quán)限認證的方式啟動
? -f 配置文件名 可以將上述的配置信息寫入到文件,然后通過該文件中的參數(shù)進行加載啟動
? 例如配置文件這樣寫:
? dbpath=數(shù)據(jù)庫存放路徑
? logpath=日志文件的存放路徑
? logappend=true(注意不能寫append)
? fork=true
? auth=true
啟動mongodb的客戶端:
? 啟動本地客戶端 mongo
? 退出 exit或者ctrl+c
? 查看幫助 mongo --help
數(shù)據(jù)庫的操作
? 查看當(dāng)前的數(shù)據(jù)庫 db (沒有切換數(shù)據(jù)庫的情況下默認使用test數(shù)據(jù)庫)
? 查看所有的數(shù)據(jù)庫 show dbs或者show databases (看不到test數(shù)據(jù)庫是因為此數(shù)據(jù)庫不在磁盤中,而是在內(nèi)存中,只能查看磁盤中存在的數(shù)據(jù)庫)
? 切換數(shù)據(jù)庫 use 數(shù)據(jù)庫名,如果數(shù)據(jù)庫不存在,則創(chuàng)建數(shù)據(jù)庫,否則切換到指定數(shù)據(jù)庫。創(chuàng)建之后show dbs并不能顯示出來,需要往里面插入數(shù)據(jù)(db.集合名.insert({key:value}) 集合若不存在會自動創(chuàng)建)或者創(chuàng)建一個集合才能將其顯示出來
? 刪除當(dāng)前的數(shù)據(jù)庫 dp.dropDatabase()
集合的操作
集合類似于mysql中的表
查看所有集合 show collections 當(dāng)沒有數(shù)據(jù)時是看不到集合的,需要先插入數(shù)據(jù)
顯示的創(chuàng)建集合 db.createCollection(名字,可選參數(shù))
? db.createCollection(“sub”,{capped:true,size:10})
? capped默認為false,表示不設(shè)置上限;size表示集合所占用的字節(jié)數(shù),當(dāng)capped為true時需要設(shè)置此參數(shù),當(dāng)文檔達到上限時,寫入數(shù)據(jù)會將之前的數(shù)據(jù)覆蓋,先覆蓋最早插入的(size的值小于等于256時,實際上都為256)
? 有上限的集合數(shù)據(jù)不允許被修改,且查詢速度也會相對較快
查看集合是否有上限 db.集合名.isCapped() false無上限,true有上限
查看集合的數(shù)據(jù) db.集合名.find()
刪除集合 db.集合名.drop()
三、常見數(shù)據(jù)類型
Object ID:文檔/數(shù)據(jù)的ID,是數(shù)據(jù)的主鍵,默認會創(chuàng)建索引
String:字符串,最常用,必須是有效的UTF-8
Boolean:布爾值,true或者false,必須是小寫
Integer:整數(shù),32或者64位,取決于服務(wù)器
Double:(雙精度)浮點數(shù)
Arrays:數(shù)組、列表
Object:mongodb中的一條數(shù)據(jù)(文檔),即文檔嵌套文檔
Null:空值
Timestamp:時間戳,表示從1970-1-1到現(xiàn)在的秒數(shù)
Date:存儲當(dāng)前日期或者時間的UNIX時間格式
注意:每個文檔都有一個屬性為_id,保證了每個文檔的唯一性,mongodb默認使用其作為主鍵,其值可以手動設(shè)置,如果沒有設(shè)置,MongoDB為每個文檔提供了一個獨特的值,類型為ObjectID
ObjectID是一個12字節(jié)的十六進制數(shù),每個字節(jié)占兩位,一共是24位(十六進制的數(shù)字字符串)
? 前四個字節(jié)(前八位):當(dāng)前時間戳
? 接下來的三個字節(jié)(六位):機器的ID
? 接下來的兩個字節(jié)(四位):MongoDB的服務(wù)進程ID
? 最后三個字節(jié)(六位):簡單的增量值
四、增刪改查
插入數(shù)據(jù)
方式一
db.集合名.insert({key:value}) key可以不加引號,終端會自動添加,value是數(shù)字不加引號,字符串必須加引號
db.集合名.insert([{},{},{}…]) 批量插入
如果想修改_id的值,插入數(shù)據(jù)時將其作為key,值作為value,放到要插入的一條數(shù)據(jù)(即文檔)前面即可
? 如:db.集合名.insert({_id:“值”,key:value})
方式二
db.集合名.save(_id:值,key:value) 如果id值已經(jīng)存在且其他數(shù)據(jù)不同則修改(會把原來數(shù)據(jù)全部刪除,更新為新數(shù)據(jù)),如果id值不存在則添加新數(shù)據(jù)
db.集合名.save(key:value) MongoDB會指定id
查詢數(shù)據(jù)
db.集合名.find() 會查詢?nèi)繑?shù)據(jù)
? db.集合名.find({條件文檔})
db.集合名.findOne() 只返回第一個
? db.集合名.findOne({條件文檔})
db.集合名.pretty() 將結(jié)果格式化,不能和findOne()一起使用
? db.集合名.find({條件文檔}).pretty()
條件文檔:
比較運算符
? 等于:默認就是等于判斷,沒有運算符
? 小于:$lt 也就是less than
? 小于等于:$lte 也就是less than euqal
? 大于:$gt 也就是greater than
? 大于等于:$gte 也就是greater than equal
? 不等于:$ne 也就是no equal
? db.stu.find({age:{$gte:18}}) 查詢年齡大于等于18的所有學(xué)生
邏輯運算符
? and:$and
? 或者直接在一個{}中寫多個條件即可
? or:$or 值為數(shù)組(列表),數(shù)組中的每個元素為json,代表一個條件
? db.stu.find({age:{$lt:18},gender:‘male’}) 查詢年齡小于18,性別為male的所有學(xué)生
? db.stu.find({KaTeX parse error: Expected '}', got 'EOF' at end of input: or:[{age:{ne:18}},{gende:‘female’}]}) 查詢年齡不等于18或者性別為female的所有學(xué)生
? db.stu.find({KaTeX parse error: Expected '}', got 'EOF' at end of input: or:[{age:{gt:18}},{age:12}],gender:“male”}) 查詢年齡大于18或者年齡等于12并且性別為male的所有 學(xué)生
范圍運算符
? $in 查找的數(shù)據(jù)是在數(shù)組內(nèi)
? $nin 查找的數(shù)據(jù)不在數(shù)組內(nèi)
? db.stu.find({age:{$in:[12,23,34]}}) 查詢年齡為12、23、34的所有學(xué)生
正則表達式
? $regex 一般存的值為字符串時使用
? db.stu.find({name:{$regex:’^黃’}}) 查詢name以“黃”開頭的所有學(xué)生
自定義查詢
? mongo shell 是一個js的執(zhí)行環(huán)境,使用$where寫一個js函數(shù),返回滿足條件的數(shù)據(jù)
? db.stu.find({$where:function(){return this.age>30;}}) 返回年齡大于30的所有學(xué)生,this類似于MySQL的游標(biāo)
對查詢結(jié)果進行操作
skip和limit
? limit(數(shù)字) 讀取指定數(shù)量的文檔
? skip(數(shù)字) 跳過指定數(shù)量的文檔
? skip的優(yōu)先級高于limit
? db.stu.find().limit(5).skip(5) 跳過前五條數(shù)據(jù),顯示后面的前五條數(shù)據(jù),改變skip和limit的前后順序結(jié)果一樣
投影
? 在查詢到的結(jié)果中只顯示選擇的字段
? db.集合名.find({},{字段名稱:1,字段名稱:1…})
? 前面的空括號填查詢條件,不寫就是查詢條件為空值為1表示顯示,值為0表示不顯示
? _id列是默認顯示的,如果不顯示需要明確設(shè)置為0
? 對于其他的字段不能既有設(shè)置為0的字段,還有設(shè)置為1的字段
? PS:除了_id之外,想看哪個字段設(shè)置為1就行啦
排序
? sort()
? db.集合名.find().sort({字段名:1,…}) 1代表升序排列,-1代表降序 排序
? db.stu.find().sort({gender:-1,age:1}) 根據(jù)性別降序排序,當(dāng)性別相同時再根據(jù)年齡升序排序
統(tǒng)計個數(shù)
? count() 統(tǒng)計查詢結(jié)果集的文檔條數(shù)
? db.集合名.find({條件}).count() 等于db.集合名.count({條件})
去重
? db.集合名.distinct(“字段名”) 只會顯示此字段名的去重后的所有值,是一個列表
? db.集合名.distinct(“字段名”,{查詢條件}) 顯示根據(jù)查詢條件查詢出來的值的此字段名的去重后的所有值
顯示操作的詳細信息
db.集合名.find().explain(“executionStats”) 可以查看操作的執(zhí)行時間等各種信息
更新數(shù)據(jù)
? db.集合名.update({查詢條件},{更新操作},{multi:true/false})
? multi為可選參數(shù),默認是false,表示只更新找到的第一條數(shù)據(jù),true表示更新滿足條件的全部數(shù)據(jù)
? db.stu.update({name:“hr”},{name:“mc”}) 會把找到的name為hr的第一條數(shù)據(jù)的name改為mc,并且會把其他的字 段值刪除
? db.stu.update({name:“hr”},{$set:{name:“mc”}}) 會把找到的name為hr的第一條數(shù)據(jù)的name改為mc,其他值不變
? db.stu.update({},{$set:{gender:“female”}},{multi:true}) 把全部學(xué)生的性別改為female
? PS:multi:true必須和$set一起使用!
? upsert參數(shù)
? db.stu.update({name:“l(fā)iu”},{$set:{age:1000}},{upsert:true}) 查詢name為liu的第一條數(shù)據(jù),如果其age值已經(jīng)是1000 則不做任何操作,如果不是則更新age的值為1000,若不存在age字段則添加此字段,如果查找失敗則插入此條數(shù)據(jù)
? 同時使用multi和upsert的話,要把它們寫到一個大括號里面,逗號隔開
刪除數(shù)據(jù)
? db.集合名.remove({查詢條件},{justOne:true/false})
? justOne可選,默認是false,表示刪除全部,為true或1表示只刪除查找到的第一條數(shù)據(jù)
? db.集合名.remove({}) 刪除此集合中的全部數(shù)據(jù),即使查詢條件為空,第一個查詢條件的{}也不能省略
五、聚合操作
聚合(aggregate)是基于數(shù)據(jù)處理的聚合管道,每個文檔通過一個由多個階段(stage)組成的管道,可以對每個階段的管道進行分組、過濾等,然后經(jīng)處理,輸出相應(yīng)的結(jié)果
db.集合名.aggregate({管道命令:{表達式}})
一個{}是一個管道
前一個管道的輸出結(jié)果作為下一個管道的輸入
常用管道命令
在mongodb中,文檔處理完畢后,通過管道進行下一次處理
$group:將集合中的文檔分組,可用于統(tǒng)計結(jié)果
$match:過濾數(shù)據(jù),只輸出符合條件的文檔
$project:修改輸入文檔的結(jié)構(gòu),如重命名、增加、刪除字段、創(chuàng)建計算結(jié)果
$sort:將輸入文檔排序后輸出
$limit:限制聚合管道返回的文檔數(shù)
$skip:跳過指定數(shù)量的文檔,并返回余下的文檔
$unwind:拆分指定的字段,爬蟲用得不多
常用表達式
表達式用來處理輸入文檔并輸出
語法:表達式:’$列名’
sum:計算總和,sum:計算總和,sum:計算總和,sum:1 表示以一倍進行個數(shù)的統(tǒng)計
$avg:計算平均值
$min:獲取最小值
$max:獲取最大值
$push:在結(jié)果的指定值插入到一個數(shù)組中
$group
db.stu.aggregate({KaTeX parse error: Expected '}', got 'EOF' at end of input: group:{_id:'gender’,sum_age:{sum:‘sum:‘sum:‘age’},name_list:{push:′push:'push:′name’}}}) _id表示以什么字段進行分組,其他的字段名可以 自己任意寫,結(jié)果是將學(xué)生安裝gender分組,并且計算每組的年齡總和,把每組的名字存到名為name_list的列表中
或者可以把整個文檔分為一組進行統(tǒng)計,查詢顯示出來的是全部文檔數(shù)據(jù)
db.stu.aggregate({KaTeX parse error: Expected '}', got 'EOF' at end of input: …:null,counter:{sum:1}}}) 相當(dāng)于db.stu.find().count()
數(shù)據(jù)透視
db.stu.aggregate({KaTeX parse error: Expected '}', got 'EOF' at end of input: …_id:null,name:{push:’$name’}}}) 把所有name放到一個列表里
db.stu.aggregate({KaTeX parse error: Expected '}', got 'EOF' at end of input: …null,data_stu:{push:’$$ROOT’}}}) 將整個文檔放入數(shù)組中
$match
和find的區(qū)別就是$match過濾出來的結(jié)果可以作為下一個管道的輸入
$match的值可以是前面提到的五種查詢方式
db.stu.aggregate({KaTeX parse error: Expected '}', got 'EOF' at end of input: match:{age:{gt:20}}}) 查詢年齡大于20的學(xué)生
db.stu.aggregate({KaTeX parse error: Expected '}', got 'EOF' at end of input: match:{age:{gt:20}}},{KaTeX parse error: Expected '}', got 'EOF' at end of input: group:{_id:"gender",counter:{$sum:1}}}) 查詢年齡大于20的男生和女生的人數(shù)
$project
類似于投影操作,輸出的結(jié)果每一條數(shù)據(jù)都在一個{}中
db.stu.aggregate({$project:{_id:0,name:1,age:1}}) 僅輸出學(xué)生的年齡和姓名
db.stu.aggregate({KaTeX parse error: Expected '}', got 'EOF' at end of input: …nder",counter:{sum:1}}},{$project:{_id:0,counter:1}}) 查詢男生和女生的人數(shù),僅輸出人數(shù)
$sort
db.stu.aggregate({$sort:{age:1}}) 查詢學(xué)生信息,按照年齡升序輸出
db.stu.aggregate({KaTeX parse error: Expected '}', got 'EOF' at end of input: …nder",counter:{sum:1}}},{$sort:{counter:-1}}) 查詢男生和女生人數(shù),按照人數(shù)降序輸出
limit和limit和limit和skip
注意和在find()中使用時的區(qū)別
db.stu.aggregate({KaTeX parse error: Expected 'EOF', got '}' at position 8: limit:2}?,{skip:1}) 會只顯示第二條數(shù)據(jù)
db.stu.aggregate({KaTeX parse error: Expected 'EOF', got '}' at position 7: skip:1}?,{limit:2}) 會只顯示第二條和第三條數(shù)據(jù)
$unwind
拆分,了解即可
db.集合名.aggregate({KaTeX parse error: Expected '}', got 'EOF' at end of input: unwind:{path:"你要拆分的字段名",preserveNullAndEmptyArrays:true})
六、索引
索引:加快查詢速度;進行數(shù)據(jù)的去重
創(chuàng)建索引后會把原先的數(shù)據(jù)結(jié)構(gòu)進行調(diào)整,調(diào)整后的結(jié)構(gòu)類似于二叉排序樹,查詢效率是O(logn)
創(chuàng)建索引
db.集合名.ensureIndex({屬性:1or-1}) 1表示升序,-1表示降序
查看索引
默認情況下_id是集合的索引
db.集合名.getIndexes()
刪除索引
db.集合名.dropIndex({“索引名稱”:1})
創(chuàng)建唯一索引
在插入數(shù)據(jù)時會檢查一下數(shù)據(jù)是否已經(jīng)存在,存在則插入失敗
會降低插入速度
db.集合名.ensureIndex({“字段名”:1},{“unique”:true})
建立復(fù)合索引
db.collection_name.ensureIndex({字段1:1,字段2:1}) 最左原則(用字段1查詢使用索引,用字段1和字段2一起查詢使用索引,但是用字段2查詢不會使用索引)
注意點:
根據(jù)需要選擇是否需要創(chuàng)建唯一索引
索引字段是升序還是降序在單個索引的情況下不影響查詢效率,但是帶復(fù)合索引的條件下會有影響
數(shù)據(jù)量巨大并且數(shù)據(jù)庫的讀出操作非常頻繁時才需要創(chuàng)建索引,如果寫入操作頻繁,創(chuàng)建索引會影響寫入速度
PS:在查詢時如果字段1需要升序的方式排序輸出,字段2需要降序的方式排序輸出,那么此時復(fù)合索引的建立需要把字段1設(shè)置為1,字段2設(shè)置為-1
一般在讀寫操作都非常頻繁且數(shù)據(jù)量巨大時采用讀寫分離的策略
七、權(quán)限管理
剛安裝的MongoDB默認不使用權(quán)限認證方式啟動,而且在安裝的時候并沒有設(shè)置權(quán)限,而公網(wǎng)運行時需要設(shè)置權(quán)限以保證數(shù)據(jù)安全。
MongoDB沒有默認的管理員賬號,所以要先添加管理員賬號,并且MongoDB服務(wù)器需要在運行的時候開啟驗證模式。
用戶只能在用戶所在的數(shù)據(jù)庫登錄(創(chuàng)建用戶的數(shù)據(jù)庫),包括管理員賬號。
管理員可以管理所有的數(shù)據(jù)庫,但是不能直接管理其他數(shù)據(jù)庫,要先認證后才可以。
創(chuàng)建超級用戶
先殺死m(xù)ongod進程
再以權(quán)限認證的方式啟動mongodb服務(wù)端
sudo mongod --auth 或者將auth=true寫入配置文件,sudo mongod -f 配置文件名,這樣啟動
打開客戶端,mongo,此時執(zhí)行數(shù)據(jù)庫各種語句會報權(quán)限錯誤,需要認證才能執(zhí)行操作
use admin 切換數(shù)據(jù)庫(名字必須是admin)
db.createUser({“user”:“用戶名”,“pwd”:“密碼”,“roles”:[“root”]}) 添加超級管理員
登錄管理員
use admin 由于是在admin數(shù)據(jù)庫上創(chuàng)建的用戶,因此必須切換到此數(shù)據(jù)庫上(用戶創(chuàng)建在哪個數(shù)據(jù)庫上就切換到哪個數(shù)據(jù)庫)
db.auth(“用戶名”,“密碼”) 顯示為1則登錄成功,為0則登錄失敗
登錄成功后就能正常執(zhí)行語句啦
創(chuàng)建普通用戶
在使用的數(shù)據(jù)庫上創(chuàng)建普通用戶
若添加了超級管理員,且以權(quán)限認證方式登錄,必須先認證后才能創(chuàng)建
use test1
db.createUser({“user”:“user1”,“pwd”:“user1”,“roles”:[“read”]}) 如果是readWrite,則是讀寫權(quán)限
show users 查看當(dāng)前數(shù)據(jù)庫中的用戶情況
在admin數(shù)據(jù)庫上創(chuàng)建普通用戶
由于在每個數(shù)據(jù)庫上面都創(chuàng)建一個用戶有些繁瑣,因此一般大多數(shù)情況下都把用戶創(chuàng)建在admin數(shù)據(jù)庫上面
use admin
先認證管理員權(quán)限 db.auth(“python”:“python”)
添加普通用戶
db.createUser({user:“user2”,pwd:“user2”,roles:[{db:“test2”,role:“read”},{db:“test3”,role:“readWrite”}]})
這里user2用戶在test2數(shù)據(jù)庫上的權(quán)限為讀,在test3上的權(quán)限為讀寫
PS:登錄user2用戶時要在admin數(shù)據(jù)庫下登錄,因為是在這個數(shù)據(jù)庫上面創(chuàng)建的此用戶!
刪除用戶
登錄超級管理員的情況下才能刪除其他用戶
先進入賬號數(shù)據(jù)所在的數(shù)據(jù)庫
db.dropUser(“用戶名”) 刪除用戶
《新程序員》:云原生和全面數(shù)字化實踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的MongoDB基础知识总结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python闭包的使用
- 下一篇: 机器学习中常见的希腊字母