初入MongoDB
阿新 • • 發佈:2020-09-11
初入MongoDB
業務需求,需要用到MongoDB。向來一直是mysql資料庫的思想,一下轉換為nosql還是很不適應。經過一個月的開發,寫一下自己的感觸。本文會對應mysql資料庫進行說明。
資料庫型別
文件型資料庫:儲存的資料是非結構化資料。文件儲存一般用類似 json 的格式儲存,儲存的內容是文件型的。
相比mysql來說,mysql的表是高度結構化的,若新增欄位可能需要修改表結構。MongoDB的話沒有這個煩惱,在其中的每條資料可以認為一個“文件”。比如,一篇文章+評論,它可以儲存為一個json,囊括了所有的資訊,直接存入資料庫。並且可以動態的橫向擴充套件,不用擔心欄位不存在的問題。
結構對比
關係型資料庫術語/概念 | MongoDB 術語/概念 | 解釋/說明 |
---|---|---|
Database | Database | 資料庫 |
Table | Collection | 資料庫表/集合 |
Row | Document | 資料記錄行/文件 |
Column | Field | 資料列/資料欄位 |
Index | Index | 索引 |
Table joins | 表關聯/MongoDB 不支援(可以使用聚合查詢) | |
Primary Key | Object ID | 主鍵/MongoDB 自動將_id 設定為 主鍵 |
接下來介紹一下專案中遇到的查詢,以nodejs為例
使用 & 高階查詢
基本查詢
//分頁排序引數 let opt = { sort: {username: 1}, skip: (value.pageNum - 1) * value.pageSize, limit: value.pageSize, } //條件 let query = {status: {$ne: -1}} if (params.keyWords) { //正則表示式 let reg = new RegExp(value.keyWords) query['$or'] = [ {nickname: reg}, {phone: reg}, ] } let admins = await AdminModel.getByQuery(query, '', opt) let admin = await AdminModel.getOneByQuery(query)
查詢方法
//查詢多條 getByQuery(query, fileds, opt) { return this.model.find(query, fileds, opt).exec(); } //查詢單條 getOneByQuery(query, fileds, opt) { return this.model.findOne(query, fileds, opt).exec(); } //數量查詢 countByQuery(query) { return this.model.countDocuments(query) } //更新 update(conditions, update, options) { return this.model.updateMany(conditions, update, options); } //去重查詢 distinct(query, field) { return this.model.find(query).distinct(field); } //儲存 save(model) { model = model instanceof this.model ? model : new this.model(model); return model.save(); } //更新 update(conditions, update, options) { return this.model.updateMany(conditions, update, options); }
關聯查詢
有時候由於業務的需要,需要關聯查詢。例如,查詢某部門的資訊,需要帶有相應的負責人。
這裡呢,需要在dept(部門表)中新增相應使用者表(user)表的objectId,就是MongoDB生成的_id
const Schema = Model.SchemaExt({
// userId為欄位名稱,ref中的“user” 代辦表名
userId: {type: ObjectId, ref: "user"}, // 負責人
code: {type: String, required: true, unique: true}, // 部門編號
name: {type: String, required: true}, // 部門名稱
//...
})
這樣的話,我們可以使用聚合查詢查詢出相關資料
//這裡的populate,代表的是欄位名稱
getByIdPopulate(id, populate) {
return this.model.findOne({_id: id}).populate(populate).exec();
}
查詢結果
{
code: 001
name: 山東分部
userId: {
_id: xxxxx,
username: xx,
phone: xxx
}
}
聚合查詢
這樣引申出另外一個問題,如果我需要根據手機號查詢部門呢
let listedModel = await deptModel.aggregate([
//關聯表,form需要關聯的表,localField自己的欄位,foreignField關聯到表的欄位,as關聯出的內容key
{
$lookup: {
from: "admins",
localField: "admin",
foreignField: "_id",
as: "adminDetail"
}
}, {
$unwind: '$adminDetail'
}, {
//查詢條件,這裡query = {'adminDetail.phone': xxx}
$match: query,
}, {
//分頁
$facet: {
data: [{
$sort: opt.sort
}, {
$skip: opt.skip
}, {
$limit: opt.limit
}],
count: [{
$group: {
_id: "count",
total: {$sum: 1}
},
}]
}
}
])