mongoose

mongoose是在node非同步環境下對mongodb進行編寫對象操作的工具


更新:建立模型時mongoose會默認添加s的坑

-------------

鏈接資料庫

安裝 mongoose: npm install --save mongoose
// 默認安裝最新5.2.4版本 該版本不支持mongodb 2.4.10及其以下版本
// mongoose v 4.13.14及其以下版本支持
// 資料庫連接不成功時注意檢查對應版本
引入 mongoose
const mongoose = require(mongoose)
// 鏈接地址: mongodb:username:password@host:prot/database
const url = mongodb://localhost:27017/data
// {useNewUrlParser: true} 使用新url解釋器 此處不加會報錯,暫時未找到原因
mongoose.connect(url, {useNewUrlParser: true}, function (err) {
if(err) {
console.log(鏈接失敗)
} else {
console.log(鏈接成功)
}
})
mongoose.disconnect(function(){ // 斷開資料庫連接
console.log(斷開鏈接)
})

mongoose.connect(url, option, callback)

點擊查看option詳情配置

Schema

用於定義資料庫的結構。類似創建表時的數據定義,每個Schema會映射到mongodb中的一個collection,Schema並不具備操作資料庫的能力

let Schema = mongoose.Schema
// 創建定義資料庫結構
const Mytest = new Schema({
name: String,
age: number,
sports: {
basketBall: String,
},
math: Mixed,
headImg: Buffer,
something: Array,
birthday: Date,
some: Boolean
})

創建Schema對象時,聲明欄位類型有兩種方法,一種是首字母大寫的欄位類型,另一種是引號包含的小寫欄位類型;

如果需要在Schema定義後添加其他欄位,可以使用add()方法.

Mytest.add({sex: String})

Model

作為Schema實例生成Model 具有抽象行為能力,可以對資料庫進行增刪改查。

· 1 創建model

const Mytest = new Schema({
name: String,
age: Number
})
// 怒填一坑 此處第一個參數在mongoose會默認添加s
// 若查詢已存在的model(不是使用mongoose新建的)填寫第三個參數為已存在的model
// 若不需要則可不填寫第三個參數
let Model = mongoose.model(myTest, Mytest, myTest)
// 新建
let mytest = new Model({
name: 測試,
ang: 12
})
// 新建後需要調用save方法
mytest.save(function (err) {
if (err) {
console.log(保存失敗,err)
} else {
console.log(保存成功)
}
})

·2 查詢

find() 參數: 查詢條件, 控制返回欄位, 查詢參數, 回調函數(err, data)
findById()
findOne()
const Mytest = new Schema({
name: String,
age: Number
})
let Model = mongose.model(myTest, Mytest)
// 查詢所有年齡大於等於10的內容。
model.find({age: {$get: 10}},function (err, docs) {})
// _id會默認輸出 若不需要_id第二參數中{_id:0}

篩選條件

條件關鍵詞|含義|條件關鍵詞|含義

------|--------|------|------$or | 或關係|$slice | 查詢欄位集合中的元素(比如從第幾個之後,第N到第M個元素$nor | 或關係取反 |$gte | 大於等於$lt | 小於|$lte | 小於等於$ne | 不等於|$in | 在多個值範圍內$nin | 不在多個值範圍內|$all | 匹配數組中多個值$regex | 正則,用於模糊查詢|$size | 匹配數組大小$maxDistance | 範圍查詢,距離(基於LBS)|$mod | 取模運算$near | 鄰域查詢,查詢附近的位置(基於LBS)|$exists| 欄位是否存在

$elemMatch | 匹配內數組內的元素|$within| 範圍查詢(基於LBS)

$box | 範圍查詢,矩形範圍(基於LBS)|$center| 範圍醒詢,圓形範圍(基於LBS)$centerSphere | 範圍查詢,球形範圍(基於LBS)

$where

進行更加複雜的查詢時,需要使用$where操作符,並且他可以使用任意的JavaScript作為查詢的一部分。

· 使用字元串

// "_id": ObjectId("aaa"), "a":1, "b":1
// "_id": ObjectId("ccc"), "a":1, "b":2
// "_id": ObjectId("ddd"), "a":1, "b":1
model.find({$where: "this.a === this.b" }, function (err, doc) {
// doc => [{
// "_id": ObjectId("aaa"), "a":1, "b":1},
// {"_id": ObjectId ("ddd"), "a":1, "b":1
// }]
})

· 使用函數

model.find({$where: function () {
return this.a === this.b // obj.a === obj.b
}})

文檔更新

共有以下幾種方式

update() updateMany() updateOne()find() + save() findOne() + save()findByIdAndUpdate() fingOneAndUpdate()

model.update(conditions, doc, option, function (err, res){})
// conditions-查詢條件 doc-需要更新的數據
*** 其中res返回 {n:2, nModified:2, ok: 1} ***
*** n為匹配到的條數 nModified修改的條數 ok 表為是否成功 ***
const option = { // option選項及其默認值
safe: true, // 安全模式
upsert: false, //如果不存在則創建新紀錄
multi: false, // 是否更新多個查詢記錄
runValidators: null, // 如果值為true,執行Validation驗證。
setDefaultsOnInsert: null, // 如果upsert選項為true,在新建時插入文檔定義的默認值。
strict: null, // 用嚴格模式跟新
overwrite: false // 禁用update-only模式,允許覆蓋記錄。
}
updateMany 默認跟新多個文檔 將選項中的multi設置為false也無效
他不會觸發跟新中間件使用 pre(updateMany) post(updateMany)
// updateOne fineOneAndUpdate 跟新找到的第一個文檔,即使將multi設置為true也無法同時跟新多個文檔。

// find + save
model.find({age: {$lt: 20}}, function (err, doc) {
if(!err) {
doc.forEach(item => {
item.age += 10
item.save()
})
}
})

// findOne + save 同上 但不需要循環

文檔刪除

共以下幾種方法

remove() findOneAndRemove() findByIdAndRemove()

remove分兩種 一種為文檔remove 一種為Model的remove
model.remove(conditions, function (err,wirteOpResult){})
// conditions查詢條件 remove 中的回調函數不能省略,否則刪除不會成功,如果強行沒有回調強制執行需要用到exec()
model.remove(conditions).exec()
findOneAndRemove 會刪除符合條件的第一條數據
model.remove(conditions, options, function(err, doc){})
// doc為刪除的文檔 同remove方法回調函數不能省略,強行沒有回調函數則需要執行exec()
findByIdAndRemove(id, options, callback) 相當於findOneAndRemove({_id: id}......)

前後中間件

前:pre() 後:post(),在執行某些操作時可以執行的函數,在Schema上指定。

在以下操作中觸發執行 中間件init validate save remove count find findOne findOneAndRemove findOneAndUpdate insertMany update

let schema = new mongoose.Schema({age: Number......})
schema.pre(find, function (next) {
// do something
console.log(我是pre)
next()
})
schema.post(find, function (doc){
console.log(我是post)
})
let model = mongoose.model(test, schema)
model.find({_id: id},function (error,doc){
if (!error) {
console.log(doc[0])
}
})
// 我是pre
// 我是post
// {_id: xxxxx, name: xxx, age: 12}

==ps: post 是在執行某些操作最後之前執行,沒有next方法==

查詢後數據處理

操作|含義

---|---sort(欄位)|排序欄位 正為從小到大 負為從大到小skip(n)|跳過n個顯示其他

limit(n)|限制顯示n個

select({age:1,_id:0})|顯示欄位 1為現實,0為不顯示exec(callback)|執行countDocuments(callback)|計數distinct(x)|顯示去重後的x [1,2]

let model = mongoose.model(test, schema)
// 按照age從小到大排序
model.find(.....).sort(age).exec(function(err, docs){})
model.find(.....).sort({age: asc}).exec(function(err, docs){})
// 從大到小排序
model.find().sort(-age).exec(function(err,docs){})
model.find().sort({age: -1}).exec(function(err,docs){})

==除去distinct操作外,其餘操作後立即斷開資料庫連接會報錯==

文檔驗證

對Schema中定義的欄位進行驗證,防止某些操作對資料庫的影響。如缺少/未設置欄位也可以保存成功等操作

常用驗證操作 | 含義----|----required| 必須填寫

default | 默認值

validate | 自定義匹配min | 最小值(只適用於數字)max | 最大值(只適用於數字)match | 正則匹配(只適用於字元串)enum | 枚舉類型(只適用於字元串)minlength | 字元串最小長度 maxlength | 字元串最大長度

const Schema = new mongoose.Schema({
age: {
type: Number,
default: 18,
min: 0,
max: 120,
},
name: {
type: String,
required: true,
validate: function (arg) {
if (arg.length > 3) {
return true
} else {
return false
}
},
}
})

推薦閱讀:

相关文章