目錄
5.2.1 使用createCollection() 方法創建集合
6.4.2 remove() 方法 刪除符合條件的第一條數據
6.4.4 deleteMany()方法 刪除所有符合條件的數據
1. MongoDB簡介
MongoDB是一個基於分佈式文件存儲的數據庫,由c++語言編寫,旨在爲 WEB 應用提供可擴展的高性能數據存儲解決方案。是目前世界上使用最多,功能最豐富的非關係型數據庫,MongoDB 是一個介於關係數據庫和非關係數據庫之間的產品,是非關係數據庫當中功能最豐富,最像關係數據庫的。
1.1 什麼是MongoDB
MongoDB是一個基於分佈式文件存儲的數據庫,由c++語言編寫.MongoDB 將數據存儲爲一個文檔,數據結構由鍵值(key=>value)對組成。MongoDB 文檔類似於 JSON 對象。字段值可以包含其他文檔,數組及文檔數組。
1.2 MongoDB的優點
MongoDB的優點是高性能,易部署,易使用,以及存儲數據非常方便
主要特點如下:
-
面向集合存儲,易存儲對象類型的數據
-
模式自由
-
支持動態查詢
-
支持完全索引,包含內部對象
-
支持查詢
-
支持複製和故障恢復
-
使用高效的二進制數據存儲,包括大型對象(如視頻等)
-
自動處理碎片,以支持雲計算層次的擴展性
-
文件存儲格式爲BSON(一種JSON的擴展)
1.3 MongoDB數據庫最重要的三個概念
數據庫(database)
數據庫就是一個倉庫,在倉庫裏可以存放集合
集合( collection)
集合類似於數組,在集合中可以存放文檔
文檔( document)
文檔數據庫中最小的單位,我們存儲和操作的內容都是文檔
一個簡單圖示來表示三者之間的關係:
一個mongodb數據庫服務器上可以有n多個database數據庫
一個database數據庫可以有n多個 collection 數據集合
一個collection 數據集合中可以有n多個 document 文檔數據
1.4 MongoDB基本概念和MySQL 基本概念對比
MySQL概念 | MongoDB概念 | 解釋說明 |
database | database | 數據庫 |
table | collection | 數據庫表/集合 |
row | document | 數據記錄行/文檔 |
column | filed | 數據字段/列 |
index | index | 索引 |
primary key | primary key | 主鍵,MongoDB自動將_id字段設置爲主鍵 |
table_joins | 表連接,MongoDB不支持 |
通過下面一張圖來更直觀的感受二者之間的區別
2. MongoDB的安裝與基本使用
2.1 官網下載mongodb
MongoDB 對於32位系統支持不好,3.2版本之後就不在支持32位系統安裝了
2.2 配置環境變量
然後依次點擊確定即可.
2.3 創建數據庫存放位置
在創建時儘量在非系統盤創建
創建一個
mongdb
文件夾,用來存儲數據和日誌在
mongodb
文件內創建db文件夾和log文件
2.4 開啓數據庫服務
使用mongod命令連接數據存放的位置,使用兩個參數鏈接數據存放的位置,和日誌存放的位置
mongod --dbpath "數據存儲位置" --logpath "日誌存儲位置"
--dbpath 表示數據存放的路徑,此時一但數據庫連接成功後光標掛起,沒有返回,
此時注意,這個CMD窗口不能關閉,一但關閉數據庫連接就關閉了
所以需要重新開一個CMD窗口操作數據庫命
我們還可以通過--port
改變數據庫默認端口
2.5 關閉數據庫服務器
mongod --shutdown
2.6 mongo命令和mongod命令
- mongo命令指的是數據庫的客戶端,用來連接數據庫服務器,對數據進行增刪改查操作.
- mongod命令是用來開啓數據庫服務器的,數據庫服務器用來保存數據.
我們會發現每次操作都需要先啓動數據庫服務器,而且服務器不能關閉,一旦不小心關係,客戶端將沒發在處理數據的操作了
所以我們可以將數據庫服務器掛在到系統服務上, 在後臺運行.開啓方法在上一篇博客中有介紹.戳鏈接即可:https://blog.csdn.net/lhrdlp/article/details/106020109
3. MongoDB基礎使用命令
3.1 進入REPL 執行環境:
進入數據庫管理模式
$ mongo
進入的是mongo的REPL環境(Read-Evel-Print-Loop,讀一句,執行一句,顯示一句)
3.2 退出REPL模式
退出數據庫管理模式
$ exit
4. 數據庫操作命令
4.1 查看所有事數據庫,顯示所有數據庫集合
一個mongodb中可以建立多個數據庫。
MongoDB的默認數據庫爲"db",該數據庫存儲在data目錄中。
MongoDB的單個實例可以容納多個獨立的數據庫,每一個都有自己的集合和權限,不同的數據庫也放置在不同的文件中。
"show dbs" 命令可以顯示所有數據的列表。
4.2. 到達指定的數據庫(use XXX)
數據庫名不存在就創建數據庫(存在就進入使用數據庫)
> use student
數據庫也通過名字來標識。數據庫名可以是滿足以下條件的任意UTF-8字符串。
- 不能是空字符串("")。
- 不得含有' '(空格)、.、$、/、\和\0 (空字符)。
- 應全部小寫。
- 最多64字節。
4.3 執行 "db" 命令可以顯示當前數據庫對象或集合
4.4 刪除數據庫
> db.dropDatabase()
5. 集合操作基礎指令
集合就是 MongoDB 文檔組,類似於 RDBMS (關係數據庫管理系統:Relational Database Management System)中的表格。
集合存在於數據庫中,集合沒有固定的結構,這意味着你在對集合可以插入不同格式和類型的數據,但通常情況下我們插入集合的數據都會有一定的關聯性。
{"site":"www.baidu.com"}
{"site":"www.google.com","name":"Google"}
{"site":"www.csdn.net","name":"CSDN","num":4}
當第一個文檔插入時,集合就會被創建。
5.1 顯示當前數據庫中的所有集合
> show collection
5.2 創建集合
5.2.1 使用createCollection() 方法創建集合
> db.createCollection(name,options)
參數:
name
創建集合的名字
options
可選參數,指定有關內存大小及索引選項
options
參數
name:集合的名字
capped:是否啓用集合限制,如果開啓需要制定一個限制條件,默認爲不啓用,這個參數沒有實際意義
size:限制集合使用空間的大小,默認爲沒有限制
max:集合中最大條數限制,默認爲沒有限制
autoIndexId:是否使用_id作爲索引,默認爲使用(true或false)
size的優先級比max要高
完整的命令示意如下:
db.createCollection(name, {capped: <Boolean>, autoIndexId: <Boolean>, size: <number>, max <number>} )
通常在創建數據時自動創建集合,不需要單獨創建,這個基本上不會用.
5.2.2 自動創建集合
如果你想創建一個集合,肯定是希望給這個集合裏添加內容, 那麼只需要正常使用集合插入數據就和了,mongodb會自動檢測,如果集合存在就正常插入,如果集合不存在,就自動創建集合
基礎語法:
db.集合名.insert(插入的數據)
示例:
> db.student.insert({name:"彭昱暢",age:26,sex:"男"})
//插入成功後的提示
WriteResult({ "nInserted" : 1 })
5.3 刪除集合
db.集合名.drop()
6. 數據庫文檔的操作命令
6.1 插入數據(新增文檔)
語法:
db.集合名.insert()
db.集合名.save()
6.1.1 insert()方法
insert()方法在插入數據是,可以插入一條數據,也可以插入多條數據
插入一條數據,參數爲一個文檔, 插入多條數據爲多個文檔的數組集合(值得注意的是,插入索條數據時是以數組的形式插入)
# 插入一條數據
db.student.insert({name:"小明",age:18})
#插入多條數據
db.student.insert([{name:"小明",age:18},{name:"小愛",age:15}])
insert方法還有兩個拆分的命令:
- insertOne 方法插入一條數據
- insertMany() 方法插入多條數據
這兩個方法就是對於insert方法的拆分,讓使用更具有寓意化
示例:
// 注意insertOne 方法只能插入一條數據,所以不能插入數組集合,會報錯
db.student.insertOne({name:"小明",age:18})
// insertMany 方法插入的是多條數據的集合,就算只插入一條數據也必須是一個數組
db.student.insertMany([{name:"小明",age:18},{name:"小愛",age:15}])
6.1.2 save()方法
save方法有更新和插入兩種功能,到底是插入還是更新文檔取決於save的參數。
具體是更新還是新增,取決於id參數。如果能根據id找到一個已經存在的文檔,那麼就更新。如果沒有傳入_id參數或者找不到存在的文檔,那麼就插入一個新文檔。
db.student.save({name:"歡歡",age:21})
這個命令是新增一條文檔, 插入的數據沒有_id,沒辦法判斷,是否存在,所以就是新增
如果先插入一個文檔:
db.student.insert({_id:"123",name:'逍遙',age:22})
注意新增數據時,沒有指定
_id
,MongoDb客戶端驅動會自動爲你生成一個默認_id
_id
的值是根據時間戳和機器碼生成的唯一ObjectId 作爲文檔的主
現在集中已經存在了_id
爲123的文檔
此時在用save方法 傳入一樣的_id
這就是在更新數據
db.student.save({_id:"123",name:'不逍遙',age:25})
> db.student.save({_id:"123",name:'逍遙',age:22})))
WriteResult({ "nInserted" : 1 })
> db.student.find()
{ "_id" : "123", "name" : "逍遙", "age" : 22 }
> db.student.save({_id:"123",name:'不逍遙',age:25})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.student.find()
{ "_id" : "123", "name" : "不逍遙", "age" : 25 }
6.1.3 save方法和insert方法對比
-
insert() 方法向集合中插入數據.若新增數據的主鍵已經存在,則會拋 org.springframework.dao.DuplicateKeyException 異常提示主鍵重複,不保存當前數據。
-
save() 方法向集合中添加或更新數據, 若新增數據的主鍵已經存在,則會對當前已經存在的數據進行修改操作。不存在則新增數據
6.2 查詢文檔
查詢文檔使用find() 方法, 查詢所有符合條件的數據,find方法可以傳入查詢的參數
語法:
- db.集合名.find()
- db.集合名.find({條件對象})
- db.集合名.findOne() 只查詢一條數據
- db.集合名.find().pretty() 將查詢的數據以格式化的結果顯示出來
6.2.1 查詢所有數據
find() 方法不傳參數或者傳入一個空對象都表示查詢集合中所有的文檔數據
db.student.find()
或
db.student.find({})
6.2.2 查詢指定數據
find() 方法中傳入參數爲查詢條件對象, 凡是符合條件的都會被查詢出來
> db.student.find({age:8})
//student集合中,所有age字段值爲18的都會被查詢出來
{ "_id" : ObjectId("5eb665916dc10adb3c4a859c"), "name" : "翃翃", "age" : 8 }
查詢對象裏可以指定多個字段
> db.student.find({name:"huanhuan",age:21})
//查詢姓名爲歡歡且年齡爲21的數據
{ "_id" : ObjectId("5eb665456dc10adb3c4a859b"), "name" : "huanhuan", "age" : 21 }
6.2.3 查詢符合條件的第一條數據
db.student.findOne({age:18})
student集合中,只查詢第一個符合name字段值爲"張三"並且 age字段值爲18的文檔(數據)
注:
- find 方法返回的是集合,也就是數組,所以可以加所以通過下標可以獲取逍遙的第幾條數據
db.student.find({age:18})[1]
- findOne 方法返回的就是符合條件的單個的文檔數據,就是一個對象
7.2.4 獲取find方法查詢獲得的數據量
既然find 方法查詢到的是一個集合(數據),那麼我們就可以通過使用count方法獲取find查詢數據的數量.
返回查詢數據的長度
db.student.find({age:18}).count()
也可以使用length 方法獲取數量
db.student.find({age:18}).length()
二者返回的結果相同
6.2.5 將數據更優雅的輸出
我們在控制檯查詢返回的結果是每一個文檔一行顯示,如果超出了控制檯的寬度看起來就不是很方便
我們可以使用pretty方法,讓每一個文檔在超出控制檯後一個字段一行顯示,這樣查詢出來的數據看起來非常舒服,非常清楚
db.student.find({age:21}).pretty()
6.3 修改文檔
修改數據的前提是你要知道修改數據,所以修改的方法傳入兩個參數,第一個參數是查詢條件,第二個參數爲修改內容
語法:
- db.集合名.update({查詢對象},{修改內容},{配置選項}),
- db.集合名.updateMany({查詢對象},{修改內容}))
db.集合名.updateOne({查詢對象},{修改內容}))
- 主鍵不能修改(除了id整體替換)
6.3.1 整體替換
在使用update 方法更新數據時應該注意,在第一個參數查詢成功後,會有第二個參數對象,直接替換原來字段中除了_id
主鍵外的其他所有字段
db.student.update({name:"小明"},{age:20})
此時查詢成功的數據將會被第二個對象所替代, 在通過find查詢是, 文檔裏面只剩下了age
一個字段
> db.student.insert({name:"小明"})
WriteResult({ "nInserted" : 1 })
> db.student.find()
{ "_id" : ObjectId("5eb8cc360aac16fef463a11f"), "name" : "小明" }
> db.student.update({name:"小明"},{age:18})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.student.find()
{ "_id" : ObjectId("5eb8cc360aac16fef463a11f"), "age" : 18 }
那麼如果只想修改制定字段的內容,其他字段不動,可以將其他字段都羅列到第二個參數對象, 很顯然這種操作很不方便
我們也可以使用修改操作符來完成制定字段的修改
6.3.2 修改指定字段的內容
修改制定字段內容的修飾操作符爲$set
屬性.
db.student.update({name:"小明"},{$set:{age:20}})
這是,字段name
值爲小明
成功的數據只會更新age字段值爲20,其他的字段都不變
> db.student.insert({name:"小明"})
WriteResult({ "nInserted" : 1 })
> db.student.find()
{ "_id" : ObjectId("5eb8cd6d0aac16fef463a120"), "name" : "小明" }
> db.student.update({name:"小明"},{$set:{age:20}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.student.find()
{ "_id" : ObjectId("5eb8cd6d0aac16fef463a120"), "name" : "小明", "age" : 20 }
>
6.3.3 刪除指定字段的修飾屬性
- $set 是修改制定字段的修飾屬性
- $unset是刪除指定字段的修飾屬性
db.student.update({name:"小明"},{$unset:{age:20}})
這個使用查詢到的文檔中age
字段就會被刪除
> db.student.insert({name:"小明"})
WriteResult({ "nInserted" : 1 })
> db.student.find()
{ "_id" : ObjectId("5eb8cd6d0aac16fef463a120"), "name" : "小明" }
> db.student.update({name:"小明"},{$unset:{age:20}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.student.find()
{ "_id" : ObjectId("5eb8cd6d0aac16fef463a120"), "name" : "小明"}
>
通過測試我們知道,update方法只能修改符合條件的第一個數據,其他的不會被修改
6.3.4 修改所有符合條件的數據
有兩種方法,
使用update方法,但是指定多文件修改的配置
使用updateMany 方法修改所有符合條件的數據
使用update,更新所有查詢到的數據sh
db.student.update({name:"pp"},{$set:{age:20}},{multi:true})
這樣所有數據符合字段name
值爲小紅
的數據,age
字段都會被修改
使用updateMany方法:
db.student.updateMany({name:"pp"},{$set:{age:20}})
6.3.5 單獨修改一條數據的方法
單獨修改一個數據的方法爲 updateOne
db.student.updateOne({name:"pp"},{$set:{age:24}})
只有第一個符合條件數據的age
字段會被修改
總結:
updateMany 方法和 updateOne 方法是 update方法拆分
6.4 刪除文檔
語法:
- db.集合名.remove({}) 刪除當前集合中的所有數據
- db.集合名.remove({條件對象}) 刪除符合條件的所有數據
- db.集合名.deleteOne() 刪除符合條件的第一個數據
- db.集合名.deleteMany() 刪除符合條件的所有數據
6.4.1 remove() 方法 刪除符合條件的所有數據
remove 方法傳參和find 方放傳參一樣, 但是remove方法不允許不傳參,會報錯
db.student.remove({name:"小明"})
所有數據中name
字段爲小明
的數據都會被刪除
6.4.2 remove() 方法 刪除符合條件的第一條數據
remove 方法可以接受第二個參數, 參數爲布爾值, 爲true就是刪除一條數據
db.student.remove({name:"didi"},true)
只會刪除數據中字段name
值爲didi的第一條數據
6.4.3 deleteOne()方法 刪除一條數據
db.student.deleteOne({age:20})
6.4.4 deleteMany()方法 刪除所有符合條件的數據
db.student.deleteMany({age:13})
6.4.5 remove () 方法清空集合
remove 方法傳入一個空對象,就是清空這個集合, 刪除所有數據
db.student.remove({})
但是這種刪除新能非常不好, 因爲這種刪除方式是一條一條數據刪除的,
如果你有需求需要刪除字段中所有的數據, 可以直接通過drap方法,刪除整個集合
db.student.drop()
一般數據庫中的數據都不會真正被刪除, 所以刪除的方法基本沒用,通常會在數據中添加一個字段來表示數據是否被刪除
注意: 由於刪除和更新操作會對數據造成極大的影響,所以一定要謹慎謹慎再謹慎.重要的事情說三遍哦>_<