Mongoose-modified-at是一个Mongoose插件,自动更新字段变化时间并记录在数据库中,类似于Mongoose自带的时间戳功能。使用场景让我们考虑一个场景。我们有发布和显示文章的要求。数据模型如下。constschema=newmongoose.Schema({//文章标题title:String,//是否是草稿is_draft:Boolean,//是否推荐is_recommended:Boolean,//更多字段...})当我们展示最新文章listing时,应该按照文章首次发布时间倒序展示,因为文章可以保存为草稿,多次编辑,所以不能使用Mongoose提供的createdAt或者updatedAt作为第一次发布时间,正确的做法是在每篇文章第一次创建或更新时,确保用户是发布文章而不是保存为草稿,然后记录这个时间,并把那个时间作为第一次出版的时间。实现这个功能需要在代码逻辑层处理,可行但有点耦合,或者自己封装一个Mongoose中间件来做,现在可以把这件事交给已经实现的插件经过测试并有一个优雅的APIModifiedAt来处理。先安装插件。npminstallmongoose-modified-at--save然后在Schema初始化的时候做简单的配置,如下。importmodifiedAtfrom'mongoose-modified-at'//在调用mongoose.model之前schema.plugin(modifiedAt,{//函数名会作为字段名写入数据库returnstrue,然后记录时间文档保存或更新is_draft字段且值为false,插件会把这次记录到你声明的publishedAt字段中,并一起写入数据库。示例如下:awaitArticle.create({title:'DocumentTitle',is_draft:false,is_recommended:true,//morefields...})结果如下(数据库):{"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){//做你想做的事情,然后返回一个布尔值告诉插件是否记录时间},})?参数说明:fields:设置监控字段,当文档创建或更新时,如果有监控字段,将自动以字段名+后缀的形式作为字段,并记录更新时间在这个领域里。可选,数组类型。suffix:设置后缀,默认值为_modifiedAt。可选,字符串类型。select:设置路径的默认行为,默认为true,参考Mongoose文档。可选,布尔类型。customField:自定义字段,该字段不会带后缀,以函数的形式添加到参数中,用于自定义函数,函数接收唯一的文档参数,当函数返回真值时,记录本次到该字段优越的。简化的API?为了增加API的简洁性和易用性,同时避免过度重载,ModifiedAt只增加了一种简化的参数传递格式,如下。schema.plugin(modifiedAt,['name','status'])意思是提取fields选项作为参数,写入数据库的结果如下。{“名字”:“汤姆”,“状态”:1,“name_modifiedAt”:ISODate(“2019-09-27T03:13:17.888Z”),“status_modifiedAt”:ISODate(“2019-09-27T03:13:17.888Z"),}要支持异步,需要Node.js版本支持async/await。importPfrom'bluebird'constpetSchema=newmongoose.Schema({name:String,age:Number,sex:String,//1:表示购买,2:购买,3:售出status:Number,})petSchema.plugin(modifiedAt,{//购买时记录asyncboughtAt(doc){//延迟1sawaitP.delay(1000)returndoc.status===2},//soldAt(doc)时记录销售地点{returndoc.status===3},})支持Mongoose4.x如果你使用的是Mongoose4.x,那么你需要使用1.x版本的插件,文档可以在这里查看。npminstallmongoose-modified-at@1--save“100%”测试覆盖率29个测试用例,777行测试代码,“100%”测试覆盖率。详细信息有关更多详细信息,请移至此处的GitHub文档。最后,1.支持,点个Star,点个Fork投稿好吗?2.本文同步发表在O2MLab博客或微信公众号。欢迎关注我们,好吗?
