一、介紹
在介紹 MongoDB 之前,我先介紹一下業務開發的時候遇到的痛點,以便大家對它有一個更加清晰的認識!
最近在用資料庫存盤資料的時候發現這么一個坑,例如從訊息佇列中監聽訊息的時候,原來的做法是將監聽的訊息資料存盤在資料庫,以便好對例外訊息資料進行追溯,訊息內容使用text型別存盤,起初因為資料內容很短,沒啥毛病,但是當隨著業務的擴展,收到的訊息內容越來越長,最后發現資料庫中的text欄位型別無法很好的支持查詢,于是在這個時候,就開始考慮采用更加合適的資料庫來存盤這種訊息資料!
在經過一番討論之后,對于這種 json 型別的訊息資料的存盤,大家一致認為采用 MongoDB 是最佳的選擇!
據官方介紹,MongoDB 是一個介于關系資料庫和非關系資料庫之間的產品,是非關系資料庫當中功能最豐富、最像關系資料庫的一款高性能的 NoSQL 資料庫,
MongoDB 將資料存盤為一個檔案,資料結構由鍵值(key=>value)對組成,
其中的檔案類似于 JSON 物件,欄位值可以包含其他檔案、陣列及檔案陣列,資料結構的支持非常靈活!
的確,在使用的程序當中,正如所介紹的,資料的存盤和查詢,性能極快,而且很好的滿足我們的需求!
話不多說,下面我們就一起來了解一下,這款資料庫應該如何使用!
二、環境配置
在學習它之前,我們需要先搭建好環境,MongoDB 的安裝也非常簡單!
2.1、Windows 平臺
如果你是 Windows 平臺,MongoDB 提供了可用于 32 位和 64 位系統的預編譯二進制,安裝基本是傻瓜式的操作,登錄 MongoDB 官網并且下載安裝包,然后一步一步的操作即可!

2.2、Linux 平臺
生產環境基本都是 Linux 平臺,為了和生產保持一致,小編采用的服務器是CentOS7,安裝程序也比較簡單!
- 創建資源檔案
sudo vim /etc/yum.repos.d/mongodb-org-4.0.repo
- 編輯內容如下
[mongodb-org-4.0]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/4.0/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-4.0.asc
- 運行以下命令安裝 mongodb
sudo yum install -y mongodb-org
- 安裝完成之后,配置
mongod.conf允許遠程連接
#編輯mongod.conf
vim /etc/mongod.conf
#將net:bindIp: 127.0.0.1 改為 0.0.0.0
net:
bindIp:0.0.0.0
- 最后啟動服務
#開啟服務
systemctl start mongod
#其他服務
#關閉服務
systemctl stop mongod
#重啟服務
systemctl restart mongod
#開機自啟
systemctl enable mongod
至此,環境配置已經完成!
三、資料庫操作
MongoDB 的資料操作,是開發人員接觸最頻繁的部分,第一次使用的時候,你會發現它和我們傳統使用的 sql 腳本命令完全不同,但是又類似,下面我們就一起來深入的了解下!
3.1、進入 MongoDB
進入 MongoDB 服務很簡單,輸入如下命令即可進入!
mongo
例如,在CentOS里面輸入命令之后,進入的服務界面如下:

3.2、創建資料庫
MongoDB 創建資料庫的語法格式如下:
use DATABASE_NAME
如果資料庫不存在,則創建資料庫,否則切換到指定資料庫,
輸入如下命令,可以查詢資料庫串列
#查詢資料庫串列
show dbs
#命令輸出結果:
admin
config
local
可以看到,當前 MongoDB 有三個資料庫!
輸入如下命令,可以切換到admin資料庫
use admin
輸入db命令,還可以查詢當前資料庫
db
3.3、創建用戶
默認的情況下,是沒有用戶的,也無法操作資料庫,因此我們需要創建一個用戶,同時給他分配權限!
3.3.1、創建一個管理員用戶
創建一個用戶、密碼都是admin的用戶,同時給這個用戶分配userAdminAnyDatabase角色,指定的資料庫為admin!
#創建一個admin用戶
db.createUser(
{
user: "admin",
pwd: "admin",
roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
})
其中欄位含義如下:
- user:用戶的名字;
- pwd:用戶的密碼;
- roles:指定用戶的角色,可以用一個空陣列給新用戶設定空角色,
- roles 中的 role:指定角色,
- roles 中的 db:指定的資料庫,例如上面中的角色
userAdminAnyDatabase,只在 admin 資料庫中可用,
角色在 MongoDB 中,代表著某個用戶是否有權限訪問資料庫或者操作資料庫,理解這點非常重要!
MongoDB 角色定義如下:
| 角色型別 | 名稱 | 描述 |
|---|---|---|
| admin資料庫角色 | readAnyDatabase | 只在admin資料庫中可用,賦予用戶所有資料庫的讀權限 |
| admin資料庫角色 | readWriteAnyDatabase | 只在admin資料庫中可用,賦予用戶所有資料庫的讀寫權限 |
| admin資料庫角色 | userAdminAnyDatabase | 只在admin資料庫中可用,賦予用戶所有資料庫的userAdmin權限 |
| admin資料庫角色 | dbAdminAnyDatabase | 只在admin資料庫中可用,賦予用戶所有資料庫的dbAdmin權限 |
| admin資料庫角色 | clusterAdmin | 只在admin資料庫中可用,賦予用戶所有分片和復制集相關函式的管理權限 |
| admin資料庫角色 | root | 只在admin資料庫中可用,超級賬號,超級權限 |
| 資料庫管理角色 | dbAdmin | 允許用戶在指定資料庫中執行管理函式,如索引創建、洗掉,查看統計或訪問system.profile |
| 資料庫管理角色 | userAdmin | 允許用戶向system.users集合寫入,可以在指定資料庫里創建、洗掉和管理用戶 |
| 資料庫用戶角色 | read | 允許用戶讀取指定資料庫 |
| 資料庫用戶角色 | readWrite | 允許用戶讀寫指定資料庫 |
3.3.2、創建一個不受訪問限制的超級用戶
如果你想創建一個不受訪問限制的超級用戶,賦予root角色即可!
#創建超級用戶
db.createUser(
{
user:"root",
pwd:"root",
roles:["root"]
}
)
3.3.3、創建一個業務資料庫普通用戶
如果你想創建一個業務資料庫普通用戶,例如只能訪問test_db資料庫,并且只負責資料的増查改刪,
# 創建或者切換資料庫到test_db
use test_db
# 創建一個test用戶,并且只能訪問test_db,對表只有讀寫權限
db.createUser(
{
user: "test",
pwd: "test",
roles: [ { role: "readWrite", db: "test_db" } ]
})
3.3.4、驗證用戶是否可以正常登錄
對于剛剛創建的用戶,我們怎么驗證它是否能正常登錄呢?命令也很簡單!
db.auth("test","test")
如果回傳是1表示鑒權正常!
3.3.5、查詢當前資料庫用戶資訊
查詢創建的用戶,命令也很簡單!
# 查看創建的用戶
show users
3.3.6、修改用戶密碼
有些時候,我們會忘記密碼,可通過如下方式進行修改!
#修改用戶密碼
db.changeUserPassword("username", "xxxxx")
3.3.7、洗掉用戶
如果某個用戶需要停用,可通過如下方式進行洗掉
#切換指定資料庫
use test_db
#洗掉用戶
db.dropUser('test')
3.3.8、洗掉資料庫
如果某個資料庫需要停用,可通過如下方式進行洗掉(只有超級管理員有權限洗掉)
#切換指定資料庫
use test_db
#洗掉資料庫
db.dropDatabase()
3.4、創建集合
MongoDB 并無表這個概念,而對應的定義叫:集合,我們在關系型資料庫中看到的表資料,在 MongoDB 中被定義為:檔案,MongoDB 也被很多人成為檔案資料庫!
在關系型資料庫中,表資料是一行一行的存盤,但是在 MongoDB 中,可能不是這樣,如果你存盤的 json 非常復雜,嵌套很深,那么在 MongoDB 中存盤的行數,可能非常深,存盤的時候類似我們在頁面看到的父子表結構!
3.4.1、創建一個集合
MongoDB 中使用 createCollection() 方法來創建集合,
語法格式:
db.createCollection(name, options)
引數說明:
- name: 要創建的集合名稱
- options: 可選引數, 指定有關記憶體大小及索引的選項
例如,在 test_db 資料庫中創建 tb_user 集合:
# 切換到test_db資料庫
use test_db
# 創建 tb_user 集合
db.createCollection("tb_user")
#輸出結果
{ "ok" : 1 }
如果要查看已有的集合,可以使用show collections命令!
show collections
下面是帶有幾個關鍵引數的createCollection()的用法,下面命令表示:創建固定集合tb_user,整個集合空間大小6142800KB, 檔案最大個數為10000 個
db.createCollection("tb_user", { capped : true, autoIndexId : true, size : 6142800, max : 10000 } )
在 MongoDB 中,很多時候不需要手動創建集合,當你插入一個檔案時,MongoDB 會自動創建集合!
# 向集合tb_user 插入一條檔案資料
db.tb_user.insert({"name" : "張三"})
#查詢集合
show collections
# 輸出結果
tb_user
3.4.2、洗掉一個集合
MongoDB 中使用 drop() 方法來洗掉集合,
語法格式:
db.collection.drop()
例如,洗掉在 test_db 資料庫中 tb_user 集合:
# 切換到test_db資料庫
use test_db
# 創建 tb_user 集合
db.tb_user.drop()
#輸出結果
true
3.4、創建檔案
創建檔案,類似我們在關系型資料庫中,將資料插入到資料庫,操作也很簡單!
3.4.1、插入檔案
MongoDB 使用 insert() 或 save() 方法向集合中插入檔案,
語法如下:
db.COLLECTION_NAME.insert(document)
或
db.COLLECTION_NAME.save(document)
save():如果_id主鍵存在則更新資料,如果不存在就插入資料,insert():若插入的資料主鍵已經存在,則會拋例外,提示主鍵重復,不保存當前資料,
例如,在test_db資料庫的tb_user集合中,插入一條資料
db.tb_user.insert(
{
name:"張三",
age:18,
gender:"男",
tags: ['宅男', '技術控', '脫發嚴重']
})
如果該集合不在該資料庫中, MongoDB 會自動創建該集合并插入檔案,
查看已插入檔案,命令如下:
#查詢tb_user集合中的資料
db.tb_user.find()
# 輸出結果
{ "_id" : ObjectId("6022310f6b5e964b0a5916e6"), "name" : "張三", "age" : 18, "gender" : "男", "tags" : [ "宅男", "技術控", "脫發嚴重" ] }
當然,你還可以通過save()命令進行插入,如果不指定_id欄位 save() 方法類似于 insert() 方法,如果指定 _id 欄位,則會更新該 _id 的資料,
例如,將張三年齡更新到30歲!
db.tb_user.save(
{
_id: ObjectId("6022310f6b5e964b0a5916e6"),
name:"張三",
age:30,
gender:"男",
tags: ['宅男', '技術控', '脫發嚴重']
})
查看檔案
db.tb_user.find()
# 輸出結果
{ "_id" : ObjectId("6022310f6b5e964b0a5916e6"), "name" : "張三", "age" : 30, "gender" : "男", "tags" : [ "宅男", "技術控", "脫發嚴重" ] }
3.4.2、更新檔案
MongoDB 提供了 update() 和 save() 方法來更新集合中的檔案,
語法格式如下:
db.collection.update(
<query>,
<update>,
{
upsert: <boolean>,
multi: <boolean>,
writeConcern: <document>
}
)
- query : update的查詢條件,類似sql update查詢內where后面的,
- update : update的物件和一些更新的運算子(如$,$inc...)等,也可以理解為sql update查詢內set后面的
- upsert : 可選,這個引數的意思是,如果不存在update的記錄,是否插入objNew,true為插入,默認是false,不插入
- multi : 可選,mongodb 默認是false,只更新找到的第一條記錄,如果這個引數為true,就把按條件查出來多條記錄全部更新,
- writeConcern :可選,拋出例外的級別,
例如,將張三年齡更新到22歲!
db.tb_user.update({'name':'張三'},{$set:{'age':22}})
查詢已更新的資料
db.tb_user.find()
# 輸出結果
{ "_id" : ObjectId("602235216b5e964b0a5916e8"), "name" : "張三", "age" : 22, "gender" : "男", "tags" : [ "宅男", "技術控", "脫發嚴重" ] }
以上陳述句只會修改第一條發現的檔案,如果你要修改多條相同的檔案,則需要設定multi引數為true,
db.tb_user.update({'name':'張三'},{$set:{'age':22}},{multi:true})
3.4.3、洗掉檔案
MongoDB 中的remove()函式是用來移除集合中的資料
語法格式如下:
db.collection.remove(
<query>,
{
justOne: <boolean>,
writeConcern: <document>
}
)
- query :(可選)洗掉的檔案的條件,
- justOne : (可選)如果設為 true 或 1,則只洗掉一個檔案,如果不設定該引數,或使用默認值 false,則洗掉所有匹配條件的檔案,
- writeConcern :(可選)拋出例外的級別,
例如,洗掉姓名為張三的用戶
db.tb_user.remove({'name':'張三'})
查詢資料是否被洗掉
db.col.find()
#結果為空
3.4.4、查詢檔案
MongoDB 查詢檔案使用 find() 方法,
語法格式如下:
db.collection.find(query, projection)
- query :可選,使用查詢運算子指定查詢條件
- projection :可選,使用投影運算子指定回傳的鍵,查詢時回傳檔案中所有鍵值, 只需省略該引數即可(默認省略),
如果你需要以易讀的方式來讀取資料,可以使用 pretty() 方法,語法格式如下:
db.col.find().pretty()
首先我們插入幾條資料,插入結果如下:

例如,查詢一個性別為男的用戶資訊
#單個條件查詢,類似 sql陳述句中的 gender = '男'
db.tb_user.find({"gender":"男"})
查詢一個性別為男,姓名為張三的用戶
#多條件查詢,類似 sql陳述句中的 gender = '男' and name = '李四'
db.tb_user.find({"gender":"男","name":"李四"})
查詢一個性別為男 或者 姓名為張三的用戶
#多條件查詢,類似 sql陳述句中的 gender = '男' or name = '李四'
db.tb_user.find({$or:[{"gender":"男"},{"name": "李四"}]})
查詢一個性別為男 或者 姓名為張三,同時年齡大于30的用戶
#多條件查詢,類似 sql陳述句中的 age > 30 and ( gender = '男' or name = '李四')
db.tb_user.find({"age": {$gt:30}, $or:[{"gender":"男"},{"name": "李四"}]})
3.4.5、分頁查詢檔案
如果需要分頁查詢集合資料,可以使用limit()和skip()函式,其中limit()表示讀幾條資料,skip()表示從第幾條資料開始,
#從集合中的第三行資料開始,讀2條資料回傳
db.tb_user.find({}).limit(2).skip(3)
3.4.6、檔案排序
和關系型資料庫一樣,MongoDB 可以使用sort()方法進行排序,通過引數指定排序的欄位,并使用 1 和 -1 來指定排序的方式,其中 1 為升序排列,而 -1 是用于降序排列,
例如,查詢tb_user檔案,按照age進行升序排序!
db.tb_user.find({}).sort({"age":1})
3.5、創建索引
索引通常能夠極大的提高查詢的效率,如果沒有索引,MongoDB 在讀取資料時必須掃描集合中的每個檔案并選取那些符合查詢條件的記錄,
這種掃描全集合的查詢效率是非常低的,特別在處理大量的資料時,查詢可以要花費幾十秒甚至幾分鐘,這對網站的性能是非常致命的,
3.5.1、創建索引
MongoDB 使用 createIndex() 方法來創建索引,語法格式如下:
db.collection.createIndex(keys, options)
語法中 Key 值為你要創建的索引欄位,1 為指定按升序創建索引,如果你想按降序來創建索引指定為 -1 即可!
例如,給tb_user檔案中的age創建一個索引!
db.tb_user.createIndex({"age":1})
創建索引是一個比較耗時的動作,我們還可以通過引數配置,在后臺創建索引,
db.tb_user.createIndex({"age":1}, {background: true})
通過在創建索引時加background:true的選項,讓創建作業在后臺執行!
3.5.2、查看索引
MongoDB 提供了getIndexes()方法,可以進行查看索引,
例如,查詢tb_user集合中的索引
db.tb_user.getIndexes()
3.5.3、洗掉索引
不在需要的索引,我們可以將其洗掉,洗掉索引時,可以洗掉集合中的某一索引,可以洗掉全部索引,
語法格式:
db.COLLECTION_NAME.dropIndex("INDEX-NAME")
例如,洗掉集合tb_user集合中的age索引:
#查詢索引
db.tb_user.getIndexes()
#輸出結果
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "test_db.tb_user"
},
{
"v" : 2,
"key" : {
"age" : 1
},
"name" : "age_1",
"ns" : "test_db.tb_user"
}
]
洗掉對應的age_1索引!
db.tb_user.dropIndex("age_1")
四、客戶端
對于任何一款資料庫,如果沒有可視化界面操作,在開發的時候,可以說極其不方便,下面推薦一款小編經常使用的一款客戶端,
- Robo 3T(免費、輕量級) ,可以訪問官網獲取

- Studio 3T(全面,收費),訪問官網地址獲取

其中小編采用的是第二款,整體的體驗比Robo 3T要一點,兩者功能都比較齊全!
在使用的時候,可以根據個人喜愛進行選擇!
五、重要的一步
網上發現很多 mongodb 被黑,使大家將目光投向了mongodb 的權限控制,
其實 mongodb 本身有一套完備的 RBAC 權限控制體系,這次被黑基本都是沒有遵照 mongodb 的生產環境部署手冊部署的結果,
我們平時玩一玩 mongodb 習慣了不設定用戶名密碼,當我們的資料庫放到公網時,由于我們也沒有設定用戶名密碼,任何人都可以隨便訪問,而且由于我們沒有開啟授權訪問,使得任何登錄到 mongodb 服務器的用戶都擁有最高權限!
一些居心不良的人發現,就可以把我們的資料拷走,洗掉我們的資料庫,從而勒索贖金!
再次提醒各位同學,別學會所有的技能,大門還一直開著,還抱怨我方防御塔怎么一直被摧毀!
以上文CentOS7安裝為例,修改/etc/mongod.conf,在security部分添加如下配置,開啟授權訪問!
security:
authorization: enabled
修改完成之后,重啟 mongodb 服務
#重啟服務
systemctl restart mongod
六、小結
本文主要圍繞 MongoDB 的使用,從環境配置、資料庫使用,再到客戶端工具選用,做了簡單的介紹,可能有的地方總結的不到位,歡迎各位網友批評指出!
在下篇文章中,我們會詳細的介紹SpringBoot和MongoDB的整合實踐!
七、參考
1、MongoDB 官方檔案
2、菜鳥教程 - mongodb
作者:程式員志哥
出處:www.pzblog.cn
資源:微信搜【Java極客技術】關注我,回復 【cccc】有我準備的一執行緒式必備計算機書籍、大廠面試資料和免費電子書, 希望可以幫助大家提升技術和能力,
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/503154.html
標籤:其他
