MongoDB-——Collection
學習大綱:
1、集合操作
2、文檔操作
知識回顧:
上一篇我們講述了如何對MongoDB的權限和用戶進行日常的基本操作,來達到我們對數據庫的基本安全保障。
一 MongoDB的集合操作
前言:
MongoDB中的集合是一組文檔的集,相當於關系型數據庫中的表。
1 創建集合
MongoDB使用db.createCollection()函數來創建集合。
語法格式:db.createCollection(name,options)
name:要創建的集合名稱
options:可選參數,指定有關內存大小及索引的選項
options 可以是如下參數
在插入文檔時,MongoDB首先檢查固定集合的size字段,然后檢查max字段
1.1 使用默認集合
在MongoDB中,我們可以不用創建集合,當我們插入一些數據時,會自動創建集合,並且會使用文檔管理命令中的集合名稱作為集合的名稱。文檔管理命令后續會詳細講解。
創建一個新數據庫,名為day(名稱自己隨意)
如果開啟認證,需要為數據庫創建訪問用戶。
新建 用戶名為day,密碼也為day 權限為writeDay 數據庫為day(這里邊用到了前邊的知識,用戶管理等。需要注意的是,創建用戶我們需要使用具有userAdminAnyDatabase權限的用戶,也就是我們前一博文創建的test,或者自己有相應權限的賬戶都可以。)
我們使用這個day用戶登錄day數據庫(最好把客戶端關閉,在重新啟動登錄,否則可能會出現問題!),並向庫中插入一條測試數據庫
查詢集合
這時候我們發現,多出了一個集合,名字就為我們的數據庫名,因為上面說過,我們沒有手動創建集合的時候,並直接插入,它會使用默認的數據庫的名字作為集合的名字生成一個集合,這時候剛剛插入的數據就在這個集合里面。
1.2 創建不帶參數的集合
我們也可以根據自己的情況創建集合。在 day數據庫中創建一個名為 day1 的集合,該集合創建時不指定任何參數。如果開啟認證,則需要使用具有數據庫管理員權限的用戶來創建集合。
1.3 創建帶參數的集合
在 develop 數據庫中創建一個名為 day2的固定集合,整個集合空間大小為 2000000kb(大約1.9g),文檔最大個數為 1000
db.createCollection('day2',{capped:true,autoIndexId:true,size:2000000,max:1000})
2 查看集合
如果要查看已有集合,可以使用 show collections 或 show tables 命令。
2.1 show collections
2.2 show tables
二 文檔操作
前言:
在MongoDb中文檔是指多個鍵及其關聯的值有序地放置在一起就是文檔,其實指的就是數據,也就是我們平時操作最多的部分。
MongoDB 中的文檔的數據結構和 JSON 基本一樣。所有存儲在集合中的數據都BSON 格式。
BSON 是一種類似 JSON 的二進制形式的存儲格式,是 Binary JSON 的簡稱
1 插入文檔
1.1 插入單個文檔
1.1.1 insert函數
語法格式:db.COLLECTION_NAME.insert(document)。
使用我們的day用戶來向day數據庫里面的day集合添加一條數據並查看
db.day.insert({title:'day',tags:['java','BigData']})
db.day.find()
1.1.2 save函數
使用我們的day用戶來向day數據庫里面的day集合添加一條數據並查看
db.day.save({title:'day1',tags:['java1','BigData1']}) db.day.find()
1.1.3 insertOne函數
在 MongoDB3.2 以后的版本中,提供了 insertOne()函數用於插入文檔。向 day集合中插入單個文檔。
使用我們的day用戶來向day數據庫里面的day集合添加一條數據並查看
db.day.insertOne({title:'day2',tags:['java2','BigData2']}) db.day.find()
1.2 插入多個文檔
向集合中批量插入多個文檔時候,需要使用數組來存放文檔
語法格式:db.COLLECTION_NAME.insert([{},{},{}.....])
1.2.1 insert或save函數實現多文檔插入
向day集合中批量插入多個文檔
db.day.insert([{title:'arebirth',tags:['a','b','c']},{title:'arebirth1',tags:['spring','mvc','collection']}])
查看文檔
這里邊的save就不演示了,跟inser操作語法一樣,只是換一個函數名字而已。
1.2.2 insertMany 函數
在 MongoDB3.2 以后的版本中,提供了 insertMany 函數用於插入文檔
語法格式:db.COLLECTION_NAME.insertMany([{},{},{},.....])
向day集合中批量插入多個文檔
db.day.insertMany([{title:'arebirth-many',tags:['a-many','b-many','c-many']},{title:'arebirth1-many',tags:['spring-many','mvc-many','collection-many']}])
查看文檔
1.3 通過變量插入文檔
Mongo Shell(也就是我們現在操作MongoDB用的工具)工具允許我們定義變量。所有的變量類型為var類型。也可以忽略變量類型。變量中的賦值符號后側需要使用小括號來標識變量中的值。我們可以將變量作為任意插入文檔的函數的參數。
語法格式:變量名=({變量值})
1.3.1 通過變量插入單個文檔
定義變量
document=({title:'SpringCloud',tags:['Spring Cloud Netflix','Spring Cloud Security','Spring Cloud Consul']})
插入文檔
我們現在將多個文檔放入到了一個變量中,所以在插入數據時,可直接使用插入單個文 檔的函數
查詢文檔
1.3.2 通過變量插入多個文檔
插入多個文檔跟單個文檔是一樣的,區別只是我們上邊學習了如果要插入多個文檔需要在文檔外圍加上中括號,數組包裹起來。
語法結構:變量名=([{},{},{},....])這里就不演示了,動手自己測試下。
使用完變量插入我們應該注意的是:
變量的有效期范圍,它只是在當前的會話內有效,如果我們超出了這個會話,就失效了。
那么會話指的是什么?就是我們在linux上打開的mongo shell客戶端,現在操作命令的客戶端,你只要把這個客戶端關閉,再重新啟動,再使用上一次聲明的變量,將會發現,已經無效了。
2 更新文檔
MongoDb通過update函數與save函數來更新集合中的文檔
2.1 update函數
update()函數用於更新已存在的文檔。
語法格式: db.集合名稱.update( <query>, <update>, < upsert:boolean>, < multi:boolean> )參數說明:
query:update的查詢條件,類似sql update更新語法內where后面的內容
update:update的對象和一些更新的操作符等,也可以理解為sql update查詢內set后面的
upsert:可選,這個參數的意思是,如果不存在update的記錄,是否插入這個document,true為插入。默認為false,不插入
multi:可選,mongodb默認是false,只更新找到的第一條記錄,如果這個參數為true,就把這個按條件查出來多條記錄全部更新。
在 MongoDB 中的 update 是有兩種更新方式,一種是覆蓋更新,一種是表達式更新。
覆蓋更新:顧名思義,就是通過某條件,將新文檔覆蓋原有文檔。表達式更新:這種更新方式是通過表達式來實現復雜更新操作,如:字段更新、數值計算、數組操作、字段名修改等。
2.1.1 覆蓋更新
覆蓋更新不能將multi參數設置為true,因為如果multi參數為true的話,只能使用表達式更新操作。
我們首先插入一條數據
db.day.insert({id:1,title:'覆蓋更新',content:'學習覆蓋更新'})
通過update方法來更新
db.day.update({id:1},{title:'更新后的內容'})
來查看下,更新后的內容
我們可以明顯發現,字段少了兩個,內容也變了,對,這就是覆蓋更新。正如它的名字一樣,“覆蓋”。所以我們要使用這個更新一定要注意,要給全所有更新項,否則就是這種狀況了。
2.1.2 表達式更新
語法: db.集合名稱.update( <query>, <doc_projection> ); doc_projection 語法: { $表達式:{具體更新規則} }
2.1.2.1 $inc
用法:{$inc:{field:value}}作用:對一個數字字段的某個field增加value
示例:將name為arebirth的學生的age增加5
測試數據
db.day.insert({name:'arebirth',age:17})命令:
db.day.update({name:'arebirth'},{$inc:{age:5}})結果:
2.1.2.2 $set
用法:{$set:{field:value}}
作用:把文檔中某個字段field的值設為value,如果field不存在,則增加新字段並將值賦值為value
示例:把arebirth的年兩設為18歲(上方的數據)
命令:
db.day.update({name:'arebirth'},{$set:{age:18}})結果:
可以自行操作下沒有的字段,看看對應的文檔是否插入了新的字段
2.1.2.3 $unset
用法:{$unset:{field:1}}
作用:刪除某個字段field 1用於占位,填寫什么數字都可以,為了滿足bson格式
示例:將arebirth的年齡的字段刪除
命令:
db.day.update({name:'arebirth'},{$unset:{age:1}})結果:
可以發現,age字段已經不存在了。
2.1.2.4 $push
用法:{$push:{field:value}}
作用:把value追加到filed里面。注意:field只能是數組類型,如果field不存在,會自動插入一個數組類型
示例:給arebirth 添加別名"boy"
命令:
db.day.update({name:'arebirth'},{$push:{alias:'boy'}})結果:
2.1.2.5 $addToSet
用法:{$addToSet:{field:value}}
作用:加一個值到數組內,而且只有當這個值不存在的時候數組才會添加進去
示例:往boy的別名字段里添加3個別名,boy、boy2、boy3
命令:
db.day.update({name:'arebirth'},{$addToSet:{alias:'boy'}})結果:
我們會發現,和原來的值沒有區別,這是因為里邊已經有相同的值了,所以不再添加。
2.1.2.6 $pop
用法:刪除數組內第一個值:{$pop:{field:-1}}、刪除數組內最后一個值:{$pop:{field:1}}
作用:用於刪除數組內一個值
示例:刪除上邊操作的數據中的name為arebirth中alias字段中最后一個別名(繞嘴)
首先添加幾個數據 db.day.update({name:'arebirth'},{$push:{alias:'boy1'}})
db.day.update({name:'arebirth'},{$push:{alias:'boy2'}})
db.day.update({name:'arebirth'},{$push:{alias:'boy3'}})
命令:
db.day.update({name:'arebirth'},{$pop:{alias:1}})
我們可以看到boy3沒了。
2.1.2.7 $pull
用法:{$pull:{field:value}}
作用:從數組field內刪除一個等於value的值
示例:刪除arebirth記錄中的別名boy2
命令:
db.day.update({name:'arebirth'},{$pull:{alias:'boy2'}})結果:
2.1.2.8 $pullAll
用法:{$pullAll:value_array}
作用:用法同$pull一樣,不同的是可以一次性刪除數組內的多個值
示例:刪除arebirth記錄內的boy1和boy別名
命令:
db.day.update({name:'arebirth'},{$pullAll:{alias:['boy1','boy']}})結果:
我們可以看見,兩個記錄都已經刪除了。
2.1.2.9 $rename
用法:{$rename:{od_field_name:new_field_name}}
作用:對字段進行重命名。底層實現是先刪除old_field字段,再創建new_field字段
示例:把arebirth記錄的name字段改名為newName
命令:
db.day.update({name:'arebirth'},{$rename:{name:'newName'}})結果:
我們可以發現名字改變了,位置也改變了,就是因為底層實現是先刪除再重建。
2.2 save函數
save()函數的作用是保存文檔,如果文檔存在則覆蓋,如果文檔不存在則新增。save函數對文檔是否存在的唯一判斷標准是"_id"系統提供的唯一字段是否匹配。所以使用save()函數實現更新操作,則必須提供“_id"字段數據。
db.集合名稱.save( <document> );參數document代表要修改的文檔內容,要求必須體哦那個"_id"字段數據
使用save()函數來實現更新操作:
db.day.save({_id:ObjectId("5dbffb7b408346b43a0df419"),newName:'rebirth'})這個上邊命令的_id根據自己客戶端上通過find()函數查找出來的為准,
結果:
之前的:
執行命令之后的:
3 刪除文檔
MongoDB是通過remove()函數、deleteOne()函數、deleteMany()函數來刪除集合中的文檔
3.1 remove 函數
語法格式是: db.集合名稱.remove( <query>, <justOne:boolean> );參數說明:
query:要刪除的文檔條件,相當於sql語句中的where子句作用
justOne:可選參數,布爾類型,代表是否只刪除第一個匹配條件滿足的文檔。默認為false,代表刪除全部滿足匹配條件的文檔:
注意:
此方法已經過時,官方推薦使用deleteOne和deleteMany函數來實現刪除操作。且remove()函數並不會真正的釋放掉存儲空間,需要刪除后,再用管理員權限的賬戶執行db.repairDatabase()函數來釋放存儲空間!
3.1.1 remove 刪除全部
刪除day集合中的全部文檔(破壞力強,慎用!)
db.day.remove({})
3.1.2 remove 條件刪除
刪除day集合中age字段為10的文檔
db.day.remove({age:10})
3.2 deleteOne 函數
語法格式: db.集合名稱.deleteOne({<query>});參數解釋:
query:要刪除的問單獨給條件,相當於sql語句中的where子句作用
刪除day集合中name字段為arebirth的第一個文檔(因為它只刪除滿足條件的第一個文檔,即使有多條,也就會刪除第一個滿足的文檔)
db.day.deleteOne({name:'arebirth'})
3.3 deleteMany 函數
參數解釋:語法格式: db.集合名稱.deleteMany({<query>});query:要刪除的文檔條件,相當於sql語法中的where子句作用
刪除day集合中字段大於10的所有文檔(這里邊用到了單條件運算符"$gt" ,我們后邊會詳細講解)
db.day.deleteMany({age:{$gt:10}})
4 查詢文檔
MongoDB是通過findOne()和find()函數來實現文檔查詢的
4.1 findOne、find函數基礎應用
4.1.1 findOne 函數
findOne 函數用於查詢集合中的一個文檔。語法如下:
db.集合名稱.findOne({ <query>}, {<projection> });參數解釋:
query:可選,代表查詢條件
projection:可選,代表查詢結果的投影字段名。即查詢結果需要返回哪些字段或不需要返回哪些字段。
首先我們用上方刪除命令清空我們的day數據庫,然后來插入幾條數據
清空 db.day.remove({}) 測試數據 db.day.insert({name:'arebirth',num:1}) db.day.insert({name:'arebirth',num:2}) db.day.insert({name:'arebirth',num:3}) db.day.insert({name:'arebirth',num:4})
查詢day集合中第一個文檔:
db.day.findOne() or db.day.findOne({})
查詢day集合中ame字段為arebirth的第一個文檔
db.day.findOne({name:'arebirth'})
查詢day集合中第一個文檔,且只顯示num字段
db.day.findOne({},{num:1})
查詢day集合中第一個文檔,且不顯示name和num字段
db.day.findOne({},{name:0,num:0})
0 不顯示 1 顯示
注意:
在 projection 中不能使用{'name':0, 'age':1}這種語法格式,這是錯誤的語法。projection 只能定義要返回的字段或不返回的字段。_id 字段是 MongoDB 維護的字段,是唯一可以在 projection 中獨立使用的。如:{_id:0, 'name':1, 'age':1}