在開發中,除了使用mongoose進行一些基本的操做外,就是一些技巧的使用。node
文章接續mongoose再認識(一),下文中使用代碼可參考這篇文章中的。git
虛擬字段,從字面意思就能夠明白,它不是真正的字段,不存在與數據庫中,可是當使用model
實例查詢時,卻能夠靈活的運用這個字段。github
注:這個特性是mongoose本身的,與mongo無關。shell
... // 添加了一個虛擬的fullname字段 // get fullname UserSchema .virtual('fullname') .get(() => this.firstname + ' ' + this.lastname) // set fullname UserSchema .virtual('fullname') .set((name) => let arr = name.split(' '), this.firstname = arr[0], this.lastname = arr[1] ) // read UserModel .find({}) .exec() .then(doc => { console.log(doc[0]) })
查詢的結果以下:數據庫
{ _id: 5c1dc7248aaf9c2c80fee915, firstname: '東坡', lastname: '蘇', __v: 0 }
那麼,如何獲取到結果fullname
呢?mongoose
能夠經過doc[0].fullname
來獲取。函數
如何對數據進行保存呢?代碼以下:post
// 模擬AJAX請求保存數據 let person2 = new UserModel() person2.fullname = '白 李' person2 .save() .then(doc => console.log(doc)) .catch(err => console.log(err))
返回結果:this
{ _id: 5c1dd7ef535df51980e9fd98, firstname: '白', lastname: '李', __v: 0 }
這樣,在開發的過程當中,就不用擔憂由於字段不匹配而須要修改數據庫的問題。這也是它存在的意義。prototype
有興趣的同窗可參考node club中對user.js
中用戶的分級,不須要在創建一個字段用來保存用戶的等級,能夠用virtual Type
經過socre
計算來得出來。
熟悉mongoose的原理的都知道,Model
的構造函數是在Schema
實例的基礎上創造出來的。因此,對於頻繁操做的Model
實例方法,能夠在Schema
的實例上進行定義(具體的可參考JavaScript的prototype)。
在一個Schema
中常常會帶有updateAt
和createAt
這樣的字段,一般的狀況下,會給它們一個默認的值。userSchema
代碼修改以下:
let UserSchema = new mongoose.Schema({ firstname: String, lastname: String, createAt: { type: Date, default: Date.now }, updateAt: { type: Date, default: Date.now } })
在開發中,開發者每每不會手動的處理它們,可是對於跟蹤記錄一個數據來講又很必要,也不容許用對這些數據任意的修改。那麼,應該如何操做它纔是最好的呢?
固然,最好就是在執行post
請求的時候,會有一些方法會根據必定機制自動保存。
而mongoose就存在這樣的機制,能夠在Schema
的實例上添加pre
的方法,代碼以下:
UserSchema.pre('save', function(next) { let now = Date.now() this.updateAt = now; if (!this.createAt) this.createAt = now; next() })
模擬AJAX請求保存數據:
let person3 = new UserModel() person3.fullname = '甫 杜' person3 .save() .then(doc => console.log(doc)) .catch(err => console.log(err))
返回結果:
{ _id: 5c1e006204bad42224374aea, createAt: 2018-12-22T09:14:10.862Z, updateAt: 2018-12-22T09:14:10.877Z, firstname: '甫', lastname: '杜', __v: 0 }
這個覺過並不能說明問題,它是Schema
定義時和pre
方法共同做用的結果。
嘗試更新數據來驗證定義的方法,代碼以下:
UserModel.findOne({ lastname: '杜' }) .exec() .then(function(doc) { doc.lastname = '杜' doc.firstname = '甫' doc.save() .then(doc => { console.log(doc) }) .catch(err => { console.error(err) }) }) .catch(err => console.log(err))
返回結果:
{ _id: 5c1e006204bad42224374aea, createAt: 2018-12-22T09:14:10.862Z, updateAt: 2018-12-22T09:15:04.398Z, firstname: '牧', lastname: '杜', __v: 0 }
這裏,咱們使用save對數據進行更新,固然這對於跟蹤用戶的操做行爲頗有好處,可是並非全部的數據都須要的,而對於哪些不須要的,仍是能夠考慮使用findOneAndUpdate,updae,updateMany的。
細心的同窗會發現,其實它和shell命令的db.users.insert({})
相似,user.save({})
是插入一條數據,然後者則能夠插入多條數據。
注:在使用操做數據庫中的數據時必定要注意,要操做的時user.find()
或user.findOne()
返回的一整條數據,若是是實例化了一個UserModel
,則會形成數據庫中的數據丟失。