1. 程式人生 > >資料庫【mongodb篇】練習操作

資料庫【mongodb篇】練習操作

本文的目標是通過大量的示例,來更好的理解如果在Mongodb中進行資料操作;

初入客戶端
剛利用 mongod命令進入客戶端環境,此時對資料庫一無所知;

舉目四望,想知道現在有哪些資料庫,

 
show dbs;

因為是新裝的mongodb環境,所以只看到了adminlocal兩個預設就存在的資料庫;目光慢慢收回,那麼當前是處於哪個資料庫上呢?

 
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();

練習增查

  1. 清空上面的school資料庫

     
    use school;
    db.dropDatabase();
    use school;
    show tables;
  2. 建立一年級的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": []
               });
           }
       }
  3. 檢視一年級二班grade_1_2中的所有學生

     
    db.getCollection('grade_1_2').find({})
  4. 檢視一年級二班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}}]})
  5. 檢視一年級二班grade_1_2中所有年齡是 4 歲或 6 歲的學生

     
    db.getCollection('grade_1_2').find({"age": {$in: [4, 6]}})
  6. 檢視一年級二班grade_1_2中所有姓名帶zhangsan1的學生

     
    db.getCollection('grade_1_2').find({"name": {$regex: "zhangsan1"}})

    檢視一年級二班grade_1_2中所有姓名帶zhangsan1zhangsan2的學生

     
    db.getCollection('grade_1_2').find({"name": {
       $in: [new RegExp(""zhangsan1"), new RegExp(""zhangsan2")]
    }})
  7. 檢視一年級二班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"]}})
  8. 檢視一年級二班grade_1_2中所有興趣愛好有三項的學生的學生數目

     
    db.getCollection('grade_1_2').find({"hobby": {$size: 3}}).count()
  9. 檢視一年級二班的第二位學生

     
    db.getCollection('grade_1_2').find({}).limit(1).skip(1)
  10. 檢視一年級二班的學生,按年紀升序

     
    db.getCollection('grade_1_2').find({}).sort({"age": 1})
     
    檢視一年級二班的學生,按年紀降序
    
     
    db.getCollection('grade_1_2').find({}).sort({"age": -1})
  11. 檢視一年級二班的學生,年齡值有哪些

     
    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})

練習刪除

  1. 一年級二班grade_1_2, 刪除所有 4 歲的學生

     
    db.getCollection('grade_1_2').remove({"age": 4})
  2. 一年級二班grade_1_2, 刪除第一位 6 歲的學生

     
    db.getCollection('grade_1_2').remove({"age": 6}, {justOne: 1})

練習修改

  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"]}}})
  2. 新學年,給一年級二班所有學生的年齡都增加一歲

     
     db.getCollection('grade_1_2').update({}, {$inc: {"age": 1}}, {multi: true})
  3. 一年級二班grade_1_2中,刪除zhangsan7學生的sex屬性

     
     db.getCollection('grade_1_2').update({"name": "zhangsan7"}, {$unset: {"sex": 1}})
  4. 一年級二班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)
            }
        });
    }
  1. 統計每名學生在考試中的總分

     
       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 }
       })
  2. 統計每名男生在考試中的總分

     
       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 }
       })
  3. 統計每名男生在考試中的總分及平均分

     
       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;
           }
       })

練習聚合

  1. 根據姓名分組, 並統計人數

     
       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}}}
       ])
  2. 統計每名學生在考試中的總分

     
       db.getCollection('grade_1_4').aggregate([
           {$group: {_id: "$name", score: {$sum: {$sum: ["$score.chinese", "$score.math", "$score.english"]}}}}
    ])
  3. 統計每名男生在考試中的總分

     
    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')