資料庫【mongodb篇】練習操作
本文的目標是通過大量的示例,來更好的理解如果在Mongodb
中進行資料操作;
初入客戶端
剛利用 mongod
命令進入客戶端環境,此時對資料庫一無所知;
舉目四望,想知道現在有哪些資料庫,
show dbs;
因為是新裝的mongodb
環境,所以只看到了admin
和local
兩個預設就存在的資料庫;目光慢慢收回,那麼當前是處於哪個資料庫上呢?
db;
通過上述這個命令,不僅可以知道當前在哪個資料庫上;
現在切換到admin
資料庫上,轉一圈;
use admin;
資料庫
這時候,筆者想要建立自己應用的資料庫school
use school;
use
命令:如果資料庫不存在,則建立資料庫,否則切換到指定資料庫;
突然發現剛才敲命令,寫錯了,寫成了use school1
;這時候,希望刪除school1
這個資料庫,就切換到該資料庫下,再鍵入刪除命令;
use school1;
db.dropDatabase();
集合Mongodb
中的集合相當於Mysql
中的表;
作為一名優秀的“校長”,能適應高資訊化社會發展,筆者需要為學校下的各個年級、班級建立集合;建立集合可以是顯式的,也可以是隱式的;
通過show tables
db.createCollection("grade_1_1");
再次通過show tables
就可以看到列表中有grade_1_1
這個集合;
當然,也可以隱式地建立,當為集合插入資料,集合不存在,這時候集合會自動建立;現在,不存在grade_1_2
“一年級二班”這個集合,執行下面語句,為“一年級二班”加入一個學生;
db.grade_1_2.insert({"name": 'zhangsan', "age": '7', "sex": "0"});
通過show tables
grade_1_2
這個集合了;
因為一些特殊原因,要解散一年級二班,那筆者這兒就不用繼續維護grade_1_2
集合,
db.grade_1_2.drop();
練習增查
-
清空上面的
school
資料庫use school; db.dropDatabase(); use school; show tables;
-
建立一年級的3個班,並隨機新增 10 名學生;
for(grade_index in (grade = ['grade_1_1', 'grade_1_2', 'grade_1_3'])) { for (var i = 1; i <= 10; i++) { db[grade[grade_index]].insert({ "name": "zhangsan" + i, "sex": Math.round(Math.random() * 10) % 2, "age": Math.round(Math.random() * 6) + 3, "hobby": [] }); } }
-
檢視一年級二班
grade_1_2
中的所有學生db.getCollection('grade_1_2').find({})
-
檢視一年級二班
grade_1_2
中所有年齡是 4 歲的學生db.getCollection('grade_1_2').find({"age": 4})
檢視一年級二班
grade_1_2
中所有年齡大於 4 歲的學生db.getCollection('grade_1_2').find({"age": {$gt: 4}})
檢視一年級二班
grade_1_2
中所有年齡大於 4 歲並且小於 7 歲的學生db.getCollection('grade_1_2').find({"age": {$gt: 4, $lt: 7}})
檢視一年級二班
grade_1_2
中所有年齡大於 4 歲並且性別值為0
的學生db.getCollection('grade_1_2').find({"age": {$gt: 4}, "sex": 0})
檢視一年級二班
grade_1_2
中所有年齡小於 4 歲並且大於 7 歲的學生db.getCollection('grade_1_2').find({$or: [{"age": {$lt: 4}}, {"age": {$gt: 6}}]})
-
檢視一年級二班
grade_1_2
中所有年齡是 4 歲或 6 歲的學生db.getCollection('grade_1_2').find({"age": {$in: [4, 6]}})
-
檢視一年級二班
grade_1_2
中所有姓名帶zhangsan1
的學生db.getCollection('grade_1_2').find({"name": {$regex: "zhangsan1"}})
檢視一年級二班
grade_1_2
中所有姓名帶zhangsan1
和zhangsan2
的學生db.getCollection('grade_1_2').find({"name": { $in: [new RegExp(""zhangsan1"), new RegExp(""zhangsan2")] }})
-
檢視一年級二班
grade_1_2
中所有興趣愛好有三項的學生db.getCollection('grade_1_2').find({"hobby": {$size: 3}})
檢視一年級二班`grade_1_2`中所有興趣愛好包括畫畫的學生
db.getCollection('grade_1_2').find({"hobby": "drawing"})
檢視一年級二班`grade_1_2`中所有興趣愛好既包括畫畫又包括跳舞的學生
db.getCollection('grade_1_2').find({"hobby": {$all: ["drawing", "dance"]}})
-
檢視一年級二班
grade_1_2
中所有興趣愛好有三項的學生的學生數目db.getCollection('grade_1_2').find({"hobby": {$size: 3}}).count()
-
檢視一年級二班的第二位學生
db.getCollection('grade_1_2').find({}).limit(1).skip(1)
-
檢視一年級二班的學生,按年紀升序
db.getCollection('grade_1_2').find({}).sort({"age": 1})
檢視一年級二班的學生,按年紀降序
db.getCollection('grade_1_2').find({}).sort({"age": -1})
-
檢視一年級二班的學生,年齡值有哪些
db.getCollection('grade_1_2').distinct('age')
檢視一年級二班的學生,興趣覆蓋範圍有哪些
db.getCollection('grade_1_2').distinct('hobby')
檢視一年級二班的學生,男生(`sex`為 0)年齡值有哪些
db.getCollection('grade_1_2').distinct('age', {"sex": 0})
練習刪除
-
一年級二班
grade_1_2
, 刪除所有 4 歲的學生db.getCollection('grade_1_2').remove({"age": 4})
-
一年級二班
grade_1_2
, 刪除第一位 6 歲的學生db.getCollection('grade_1_2').remove({"age": 6}, {justOne: 1})
練習修改
-
一年級二班
grade_1_2
中,修改名為zhangsan7
的學生,年齡為 8 歲,興趣愛好為 跳舞和畫畫;db.getCollection('grade_1_2').update({"name": "zhangsan7"}, {$set: {"age": 8, "hobby": ["dance", "drawing"]}})
一年級二班`grade_1_2`中,追加zhangsan7`學生興趣愛好唱歌;
db.getCollection('grade_1_2').update({"name": "zhangsan7"}, {$push: {"hobby": "sing"}})
一年級二班`grade_1_2`中,追加zhangsan7`學生興趣愛好吹牛和打籃球;
db.getCollection('grade_1_2').update({"name": "zhangsan7"}, {$push: {"hobby": {$each: ["brag", "play_basketball"]}}})
一年級二班`grade_1_2`中,追加`zhangsan7`學生興趣愛好唱歌和打籃球,要保證`hobby`陣列不重複;
db.getCollection('grade_1_2').update({"name": "zhangsan7"}, {$addToSet: {"hobby": {$each: ["sing1", "play_basketball"]}}})
-
新學年,給一年級二班所有學生的年齡都增加一歲
db.getCollection('grade_1_2').update({}, {$inc: {"age": 1}}, {multi: true})
-
一年級二班
grade_1_2
中,刪除zhangsan7
學生的sex
屬性db.getCollection('grade_1_2').update({"name": "zhangsan7"}, {$unset: {"sex": 1}})
-
一年級二班
grade_1_2
中,刪除zhangsan7
學生的hobby
陣列中的頭元素db.getCollection('grade_1_2').update({"name": "zhangsan7"}, {$pop: {"hobby": -1}})
一年級二班`grade_1_2`中,刪除`zhangsan7`學生的`hobby`陣列中的尾元素
db.getCollection('grade_1_2').update({"name": "zhangsan7"}, {$pop: {"hobby": 1}})
一年級二班`grade_1_2`中,刪除`zhangsan7`學生的`hobby`陣列中的`sing`元素
db.getCollection('grade_1_2').update({"name": "zhangsan7"}, {$pull: {"hobby": "sing"}})
練習分組
新建一個集合grade_1_4
,記錄一年級四班在期中考試時的成績;
for (var i = 1; i <= 10; i++) {
db.grade_1_4.insert({
"name": "zhangsan" + i,
"sex": Math.round(Math.random() * 10) % 2,
"age": Math.round(Math.random() * 6) + 3,
"score": {
"chinese": 60 + Math.round(Math.random() * 40),
"math": 60 + Math.round(Math.random() * 40),
"english": 60 + Math.round(Math.random() * 40)
}
});
}
-
統計每名學生在考試中的總分
db.grade_1_4.group({ key: {"name": 1}, cond: {}, reduce: function(curr, result) { result.total += curr.score.chinese + curr.score.math + curr.score.english; }, initial: { total : 0 } })
-
統計每名男生在考試中的總分
db.grade_1_4.group({ key: {"name": 1}, cond: {"sex": 0}, reduce: function(curr, result) { result.total += curr.score.chinese + curr.score.math + curr.score.english; }, initial: { total : 0 } })
-
統計每名男生在考試中的總分及平均分
db.grade_1_4.group({ key: {"name": 1}, cond: {"sex": 0}, reduce: function(curr, result) { result.total += curr.score.chinese + curr.score.math + curr.score.english; }, initial: { total : 0 }, finalize: function(item) { item.avg = (item.total / 3).toFixed(2); return item; } })
練習聚合
-
根據姓名分組, 並統計人數
db.getCollection('grade_1_4').aggregate([ {$group: {_id: "$name", num: {$sum: 1}}} ])
根據姓名分組, 並統計人數,過濾人數大於 1 的學生
db.getCollection('grade_1_4').aggregate([ {$group: {_id: "$name", num: {$sum: 1}}}, {$match: {num: {$gt: 1}}} ])
-
統計每名學生在考試中的總分
db.getCollection('grade_1_4').aggregate([ {$group: {_id: "$name", score: {$sum: {$sum: ["$score.chinese", "$score.math", "$score.english"]}}}} ])
-
統計每名男生在考試中的總分
db.getCollection('grade_1_4').aggregate([ {$match: {sex: 0}}, {$group: {_id: "$name", score: {$sum: {$sum: ["$score.chinese", "$score.math", "$score.english"]}}}} ])
統計每名男生在考試中的總分, 總分降序
db.getCollection('grade_1_4').aggregate([ {$match: {sex: 0}}, {$group: {_id: "$name", score: {$sum: {$sum: ["$score.chinese", "$score.math", "$score.english"]}}}}, {$sort: {score: 1}} ])
練習許可權
建立使用者
要讓許可權生效,需要
mongo
伺服器啟動時新增--auth
選項;
建立使用者school_admin
,只能對school
資料庫進行讀寫操作;
use school;
db.createUser({
user: "school_admin",
pwd: "school_admin",
roles: [{role: "readWrite", db: "school"}]
})
關於第三個引數角色,看下錶:
角色名 | 描述 |
---|---|
Read | 允許使用者讀取指定資料庫 |
readWrite | 允許使用者讀寫指定資料庫 |
dbAdmin | 允許使用者在指定資料庫中執行管理函式,如索引建立、刪除,檢視統計或訪問system.profile |
userAdmin | 允許使用者向system.users 集合寫入,可以找指定資料庫裡建立、刪除和管理使用者 |
clusterAdmin | 只在admin 資料庫中可用,賦予使用者所有分片和複製集相關函式的管理許可權 |
readAnyDatabase | 只在admin 資料庫中可用,賦予使用者所有資料庫的讀許可權 |
readWriteAnyDatabase | 只在admin 資料庫中可用,賦予使用者所有資料庫的讀寫許可權 |
userAdminAnyDatabase | 只在admin 資料庫中可用,賦予使用者所有資料庫的userAdmin 許可權 |
dbAdminAnyDatabase | 只在admin 資料庫中可用,賦予使用者所有資料庫的dbAdmin 許可權 |
root | 只在admin 資料庫中可用。超級賬號,超級許可權 |
驗證使用者
如果未通過驗證,進行查詢,
會得到如下的提示:
Error: error: {
"ok" : 0,
"errmsg" : "not authorized on school to execute command { find: \"grade_1_2\", filter: {} }",
"code" : 13,
"codeName" : "Unauthorized"
}
如果執行驗證程式碼:注意,要在註冊時所在的資料庫中驗證
use school;
db.auth('使用者名稱', '密碼')
檢視所有使用者
db.getUsers()
刪除使用者
先移到使用者註冊的資料庫,然後移除指定使用者 school_admin
db.dropUser('school_admin')