MongoDB核心
基礎概念
數據庫
- 數據庫是按照數據結構來組織、存儲和管理數據的倉庫。
- 在內存中運行的,一旦程序運行結束或者計算機斷電,程序運行中的數據都會丟失。
- 我們需要將一些程序運行的數據持久化到硬盤之中,以確保數據的安全性。
- 數據庫就是數據持久化的最佳選擇。數據庫就是存儲數據的倉庫。
數據庫分類
關系型數據庫:
- MySQL、Oracle、DB2、SQL Server ······
- 關系型數據庫中全是表
非關系型數據庫:
- ?MongoDB、 Redis ······
- 鍵值對數據庫
MongoDB
- MongoDB 是一個基于分布式文件存儲的數據庫.
- MongoDB 是為快速開發互聯網 Web 應用而設計的數據庫系統。
- MongoDB 的設計目標是極簡、靈活、作為Web 應用棧的一部分。
- MongoDB 的數據模型是面向文檔的,所謂文檔是一種類似于 JSON 的結構,簡單理解
MongoDB 這個數據庫中存的是各種各樣的JSON. (BSON)
在MongoDB中有三個重要概念:
- 數據庫 (database):
數據庫是一個數據倉庫,數據庫服務下可以創建多個數據庫,數居庫中可以存放多個集合 - 集合 (collection):
集合類似于 JS 中的數組,在集合中可以存放很多文檔 - 文檔 (document)
文檔是數據庫中的最小單位,類似于 JS 中的對象
與JSON來對比:
- JSON文件==>數據庫
- JSON中的一級數組==>集合
- 數組中的對象==>文檔?
MongoDB Shell
MongoDB Shell 是 MongoDB 提供的官方交互式界面,允許用戶與 MongoDB 數據庫進行交互、執行命令和操作數據庫。
MongoDB Shell 是基于 JavaScript 的,允許用戶直接在命令行或者腳本中使用 JavaScript 語言來操作 MongoDB 數據庫。
安裝完成后,可以來使用 MongoDB Shell 連接到 MongoDB 數據庫并執行操作。
數據庫命令
1.顯示所有數據庫
show dbs
2.?切換到指定的數據庫
use 數據庫名
注:如果數據庫不存在會自動創建數據庫。如果數據庫內沒有集合,show dbs指令不會顯示該數據庫
3.顯示當前所在的數據庫
db
4.?刪除當前數據庫
use 庫名db.dropDatabase ()
集合命令
1.?創建集合
db.createCollection (' 集合名稱 ')
2.顯示當前數據庫中的所有集合
show collections
3.刪除某個集合
db. 集合名.drop
4.重命名集合
db.集合名.renameCollection('newName')
文檔命令
1.插入文檔
db. 集合名.insert (文檔對象)
2.查詢文檔
db. 集合名.find (查詢條件)例:db.test.find({name:'張三'})
注:查詢后結果中,_id 是 mongodb 自動生成的唯一編號,用來唯一標識文檔
3. 更新文檔
db. 集合名.update (查詢條件,新的文檔)例:db. test.update ({name: 張三 '},{$set:{age:19}})
注:如果新文檔不使用$set則會覆蓋舊文檔?
4.刪除文檔
db. 集合名.remove (查詢條件)
Mongoose
Mongoose簡介
Mongoose (http://www.mongoosejs.net)是一個對象文檔模型庫
可以讓我們使用代碼來進行操作 mongodb 數據庫
使用方法
連接數據庫
首先需要安裝Mongoose
npm i mongoose
//導入mongoose
const mongoose = require('mongoose');//連接數據庫 mongodb://ip:端口/數據庫名
mongoose.connect('mongodb://127.0.0.1:27017/test')//設置回調函數
//連接成功回調
mongoose.connection.once('open', () => {console.log('數據庫連接成功')
})//連接失敗回調
mongoose.connection.once('err', () => {console.log('數據庫調用失敗');
})//連接關閉回調
mongoose.connection.once('close', () => {console.log('數據庫連接關閉');
})//開啟定時器,關閉鏈接
setTimeout(() => {mongoose.disconnect()
}, 3000)
創建文檔結構對象和文檔模型對象
//導入mongoose
const mongoose = require('mongoose')//鏈接數據庫
mongoose.connect('mongodb://127.0.0.1:27017/dome')//創建文檔結構對象
//該對象用于規定文檔結構
let gameSchema = new mongoose.Schema({name: String,price: Number
})//創建文檔模型對象
//該對象內封裝方法,用于操作數據庫
//傳參(集合名,文檔結構對象)
let gameModel = mongoose.model('games', gameSchema)//設置鏈接成功后的回調
mongoose.connection.once('open', () => {console.log('數據庫連接成功');testDocumentation() //調用封裝好的方法進行增刪改查
})
字段值驗證
?Mongoose 有一些內建驗證器,可以對字段值進行驗證
字段值驗證在創建文檔結構對象時進行
let personSchema = new mongoose.Schema({name: {type: String,required: true //必填項},age: {type: Number,default: 18 //默認值},sex: {type: String,enum: ['男', '女'] //枚舉值,設置的值必須是數組中的},card: {type: Number,unique: true //唯一值,新建集合才有效果}
})
添加文檔(增)
添加文檔,可以使用文檔模型對象中的create方法來添加,批量添加可以使用insertMany方法
添加一條時,傳入參數為符合文檔結構對象的對象
async function AddDocumentation() {//添加文檔//使用文檔模型對象中的create方法try {let add = await gameModel.create({name: '艾爾登法環',price: 298})console.log(add);} catch (error) {console.log(error);}//關閉數據庫mongoose.disconnect()
}
添加多條,傳入數組,數組內為符合文檔結構對象的對象
//增加多條
async function AddDocumentationMany() {try {let add = await gameModel.insertMany([{name: '無限機兵',price: 159},{name: '匹諾曹',price: 298}])console.log(add);} catch (err) {console.log(err);}//關閉數據庫mongoose.disconnect()
}
注:Mongoose 6.x 版本之后的 API 變更。從 Mongoose 6 開始,所有的異步操作(如?Model.create()
、find()
、save()
?等)都不再支持回調函數,而是強制使用 Promise 或?async/await
?語法。
控制臺輸出:
刪除文檔(刪)
刪除使用?deleteOne方法和deleteMany方法。
傳入一個查詢參數即可
deleteOne為單獨刪除
async function DeleteDocumentOne() {try {let Delete = await gameModel.deleteOne({_id: '68522ffc56b9a48fd708b8fc'})console.log(Delete);} catch (err) {console.log(err);}mongoose.disconnect()
}
deleteMany為批量刪除
async function DeleteDocumentMany() {try {let Delete = await gameModel.deleteMany({name: '黑暗之魂1'})console.log(Delete);} catch (err) {console.log(err);}mongoose.disconnect()
}
?控制臺輸出:
?
更新文檔(改)
更新使用?updateOne方法和updateMany方法。
需要傳入兩個參數,第一個為查詢參數,第二個為更新參數
該方法是直接在舊文檔進行修改,不存在新文檔覆蓋舊文檔,故不用$set
updateOne為單獨更新
async function UpdateDocumentOne() {try {let update = await gameModel.updateOne({ _id: '68523020764ff87f3b7cabbd' },{ name: '魂5' })console.log(update);} catch (err) {console.log(err);}mongoose.disconnect()
}
updateMany為批量更新
async function UpdateDocumentMany() {try {let update = await gameModel.updateMany({ name: '黑暗之魂3' },{ price: 99 })console.log(update);} catch (err) {console.log(err);}mongoose.disconnect()
}
?控制臺輸出:?
?
?查詢文檔(查)
查詢分為單獨查詢,ID查詢和批量查詢
分別使用 findOne ( ) , findById ( ) ,?find ( ) 方法
單獨查詢需要傳入查詢參數,ID查詢需要傳入ID,批量查詢傳不傳參數都可以
批量查詢若不傳參,則為查詢全部數據
單獨查詢:
//查詢一條數據
async function FindDocumentOne() {try {let find = await gameModel.findOne({ name: '無限機兵' })console.log(find);} catch (err) {console.log(err);}
}
ID查詢:
//通過ID查詢
async function FindDocumentID() {try {let find = await gameModel.findById('6852817f3870d51a37a2df25')console.log(find);} catch (err) {console.log(err);}
}
批量查詢:
//批量查詢
async function FindDocumentMany() {try {let find = await gameModel.find({ name: '魂5' })console.log(find);} catch (err) {console.log(err);}
}
控制臺輸出:
?條件控制
在查詢文檔時,我們可以設置查詢的條件,來獲取我們想要的數據
運算符
在mongodb中不可以使用 >? <? = 等運算符,需要使用相應的符號來替換
運算符 | 代替符號 |
> | $gt |
< | $lt |
>= | $gte |
<= | $lte |
!== | $ne |
使用語法:
{ 屬性名: { 運算符: 值 } }示例:
let find01 = await gameModel.find({ price: { $lt: 200 } })
?邏輯運算
運算符 | 邏輯 |
$or | 邏輯或 |
$and | 邏輯與 |
使用語法:
{ 運算符: [{ 屬性名: 值 }, { 屬性名: 值 }
] }示例:
let find02 = await gameModel.find({ $or: [{ price: 298 }, { price: 99 }] })
混合用法:
let find03 = await gameModel.find({ $or: [{ price: { $lt: 300 } }, { price: { $gt: 100 } }] })
正則匹配
條件中可以直接使用正則匹配
let find04 = await gameModel.find({ name:/魂/ })let find04 = await gameModel.find({ name: new RegExp('魂') })
個性化讀取
字段篩選
在讀取完文檔后,對象中的一部分數據并不一定是我們所需要的
可以通過字段篩選來獲取我們想要的屬性
語法:
文檔模型對象 . find ( ) . select ( {? 屬性名 : 0 , 屬性名: 1?} )
0:不要的字段? ? 1:要的字段
//批量查詢
async function FindDocumentMany() {try {let find01 = await gameModel.find().select({ _id: 0, name: 1, price: 1 })console.log(find01);} catch (err) {console.log(err);}mongoose.disconnect()
}
數據排序?
根據規定屬性值排序
語法:
文檔模型對象 . find ( ) . sort( {? 屬性名 : 0 / 1??} )
0:倒序? 1:正序
//批量查詢
async function FindDocumentMany() {try {let find01 = await gameModel.find().select({ _id: 0, name: 1, price: 1 }).sort({ price: 1 })console.log(find01);} catch (err) {console.log(err);}mongoose.disconnect()
}
數據截取
從指定位置獲取到指定數量的數據
語法:
文檔模型對象 . find ( ) . skip( 數字 )? //跳過幾個數據
文檔模型對象 . find ( ) . limit( 數字 )? ?//獲取幾個數據
//批量查詢
async function FindDocumentMany() {try {let find01 = await gameModel.find().select({ _id: 0, name: 1, price: 1 }).sort({ price: 1 }).skip(2).limit(3)console.log(find01);} catch (err) {console.log(err);}mongoose.disconnect()
}