Mongoose-modified-at 時間自動記錄插件介紹

Mongoose-modified-at 是一款自動更新字段變化時間並記錄到數據庫中的 Mongoose 插件,相似 Mongoose 自帶的 timestamps 功能。javascript

使用場景

讓咱們考慮一個場景,咱們有個文章發佈與展現的需求,數據模型以下。html

const schema = new mongoose.Schema({
  // 文章標題
  title: String,
  // 是否爲草稿
  is_draft: Boolean,
  // 是否推薦
  is_recommended: Boolean,
  // 更多字段...
})
複製代碼

當咱們在展現最新文章列表時,應該是以文章第一次發佈的時間倒序展現,由於文章能夠存爲草稿,屢次編輯,因此不能用 Mongoose 提供的 createdAtupdatedAt 做爲第一次發佈的時間,正確的作法是在每次文章建立或更新時,肯定用戶是發佈文章而不是存爲草稿,而後記錄這次時間,用該時間做爲第一次發佈的時間。java

要實現該功能咱們須要在代碼邏輯層進行處理,這樣可行不過有點耦合,或者本身封裝一個 Mongoose 中間件來作這件事,不過如今你能夠把這件事交給一個經受測試、API 優雅的插件 ModifiedAt 來處理。git

首先安裝插件。github

npm install mongoose-modified-at --save
複製代碼

而後在 Schema 初始化時作簡單的配置便可,以下。數據庫

import modifiedAt from 'mongoose-modified-at'

// 在 mongoose.model 調用以前
schema.plugin(modifiedAt, {
  // 函數名將做爲字段名寫入數據庫
  publishedAt(doc) {
    // 當函數返回值爲 true 時,則記錄該時間
    return !doc.is_draft
  },
  // 推薦文章也是如此
  recommendedAt(doc) {
    return doc.is_recommended
  },
})

const Article = mongoose.model('Article', schema)
複製代碼

當文檔保存或更新攜帶着 is_draft 字段而且值爲 false 時,插件就會記錄這次時間到你聲明的 publishedAt 字段上一塊兒寫入數據庫。npm

示例以下:api

await Article.create({
  title: 'Document Title',
  is_draft: false,
  is_recommended: true,
  // 更多字段...
})
複製代碼

結果以下(數據庫):bash

{
  "title": "Document Title",
  "is_draft": false,
  "is_recommended": true,
  "publishedAt": ISODate("2019-09-27T03:11:07.880Z"),
  "recommendedAt": ISODate("2019-09-27T03:11:07.880Z"),
  // 更多字段...
}
複製代碼

附加案例

做爲漸進式項目,咱們的開發通常也是漸進式的,雖然咱們會不自覺地超前考慮,可是仍是不能徹底考慮到將來需求的變化,假如咱們對某個項目的功能已經完成並穩定上線了,後來好比咱們須要作數據統計分析的工做,這項工做的分析維度對時間的精度要求比較高,因此要是咱們在開發時並無考慮到要添加這些時間字段(由於可能對業務不是必須的),而如今須要加上這些字段,要是去原來的代碼基礎上改動添加,若是改動的地方少還好,若是有完善的測試用例還好,不然這也許會改的心驚膽戰,由於你須要確保每一處改動不會產生錯誤影響。因此此時,使用無侵入式的中間件插件 ModifiedAt 那就省心不少了,只需在模型出口簡單配置,無需改動邏輯層代碼,便可實現剛剛想要的功能。微信

API介紹

上面是 ModifiedAt 的富 API 形式,即對象格式,所有參數選項以下。

schema.plugin(modifiedAt, {
  // 設置監聽字段
  fields: ['name', 'status', 'another'],
  // 設置後綴
  suffix: '_your_suffix',
  // 設置路徑默認行爲
  select: true,
  // 自定義字段
  customField(doc) {
    // 作一些你想作的事,而後返回 Boolean 值,告訴插件是否記錄時間
  },
})
複製代碼

🍎 參數解釋:

  • fields: 設置監聽字段,在文檔建立或更新時,若是存在被監聽的字段,則自動以 字段名 + 後綴 的形式做爲字段,並記錄這次更新時間到該字段上。可選,Array 類型。
  • suffix: 設置後綴,默認值爲 _modifiedAt。可選,String 類型。
  • select: 設置路徑默認行爲,默認爲 true參考 Mongoose 文檔。可選,Boolean 類型。
  • customField: 自定義字段,此字段不會加後綴,以函數形式添加到參數中,用於自定義功能,函數接收惟一文檔參數,當函數返回值爲真值時,則記錄這次時間到該字段上。

簡化API

🚀 爲了增長 API 的簡潔易用同時避免過分重載,ModifiedAt 只增長了一種簡化傳參格式,以下。

schema.plugin(modifiedAt, ['name', 'status'])
複製代碼

意思是將 fields 選項提取出來做爲參數,寫入數據庫的結果以下。

{
  "name": "Tom",
  "status": 1,
  "name_modifiedAt": ISODate("2019-09-27T03:13:17.888Z"),
  "status_modifiedAt": ISODate("2019-09-27T03:13:17.888Z"),
}
複製代碼

支持異步

你須要 Node.js 版本支持 async/await 便可。

import P from 'bluebird'

const petSchema = new mongoose.Schema({
  name: String,
  age: Number,
  sex: String,
  // 1:表示採購中,2:已購買,3:已售出
  status: Number,
})

petSchema.plugin(modifiedAt, {
  // 記錄購買於哪時
  async boughtAt(doc) {
    // 延時 1s
    await P.delay(1000)
    return doc.status === 2
  },
  // 記錄售出於哪時
  soldAt(doc) {
    return doc.status === 3
  },
})
複製代碼

支持 Mongoose 4.x

若是你如今使用的是 Mongoose 4.x,那麼你須要使用插件 1.x 版本,文檔可在這裏查看

npm install mongoose-modified-at@1 --save
複製代碼

「100%」測試覆蓋率

29 個測試用例,777 行測試代碼,「100%」 測試覆蓋率。

細節

更多細節處理請移步至 GitHub 文檔,這裏

最後

一、支持一下,煩請點個 Star 吧,貢獻就點個 Fork 吧 😘

二、本文同步發表於凹凸實驗室博客或微信公衆號,歡迎關注咱們,麼麼噠 😍

相關文章
相關標籤/搜索