mongoose再认识(二)

在开发中,除了使用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计算来得出来。

在Schema定义一些Model实例经常使用的方法

熟悉mongoose的原理的都知道,Model的构造函数是在Schema实例的基础上创造出来的。因此,对于频繁操做的Model实例方法,能够在Schema的实例上进行定义(具体的可参考JavaScript的prototype)。

在一个Schema中常常会带有updateAtcreateAt这样的字段,一般的状况下,会给它们一个默认的值。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,则会形成数据库中的数据丢失。

mongoose系列文章

相关文章
相关标签/搜索