博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Mongoose返回数据修改中遇到的坑
阅读量:6491 次
发布时间:2019-06-24

本文共 2381 字,大约阅读时间需要 7 分钟。

之前接手了一个微信公众号的项目,项目的技术栈是: NodeJs+ExpressJs+mongo+mongoose+jade,第一次使用ODM(Object DatabaseManage)工具mongoose,发现使用起来还是非常方便的,你可以预先定义一个model,把mongo这种NoSql当做关系型数据库使用,并且通过populate能基本实现一些比较简单的连接查询 ,但是在使用的过程中也是踩了不少坑,举例讲一个比较典型的:对于mongoose返回数据的修改的问题。

假设我们需要涉及一个关于评论的model,我们用下面的代码举例:

var mongoose = require('mongoose');var Schema = mongoose.Schema;var CommentSchema = new Schema({    topicId: {type: Schema.ObjectId, ref:'Topic',index: true},    author: { type: Schema.ObjectId, ref: 'User'},    group: {type: Number, default: 0, index: true},    content: String,    status: {type: Number, default: 0},    createdAt: { type: Date, default: Date.now },    favNum: {type:Number, default: 0}});var Comment = mongoose.model('Comment', CommentSchema);module.exports = Comment;

  上面的代码非常的简单明了,定义了model的各种字段、类型、引用,这样我们在代码中就可以通过mongoose对mongo进行查询了,有Java的经验老司机会发现这个工具和Hibernate非常相似。

  假设现在我们有一个业务,我需要提供一个Restful Get接口,返回当前文章的评论信息,并且根据session判断登录用户,去对每条评论判断是否该登录用户已经点赞,那么我想要在返回的数据中临时增加一个字段isPraisetrue代表是当前登录用户已经点赞,false代表当前用户未点赞。
  我们可能会有下面两种mongoose的代码风格

Comment.findOne({    id: commentId,},function (err,data) {    if(){        //如果用户点赞        data.isPraise = true;    }else{        //如果用户未点赞        data.isPraise = false;    }});

或者

Comment.findOne({    id: commentId}).exec(function (err,data) {    if(){        //如果用户点赞        data.isPraise = true;    }else {        //如果用户未点赞        data.isPraise = false;    }});

  上面的代码看起来没有任何的问题,mongoose返回的是Object,我根据自己的业务新增属性,然后以JSON数据返回给用户。但是事实上新增加的属性不能被打印出来(通过console.log(JSON.stringify(data)))也不能返回给客户端,但是奇怪的是却可以打印出来console.log(data.isPraise),而且Object.prototype.hasOwnProperty()方法返回的也是true,说明确实已经增加了这个属性,为什么不会返回给请求方呢?

  后面经过排查终于发现了问题的所在,实际上mongoose返回的数据并不是object,虽然你通过typeof判断类型是object,实际上是mongoose自己封装的一个对象,并且这个对象会对数据进行实时查询以保证其符合预定义的model,因为model中压根就没有isPraise属性,所以是无法增加的。
  现在看来解决方法可以在model中预先定义isPraise字段,但是这个并不是没有业务都需要的,所以这种方法太糙了,果断放弃。幸好mongooes提供给我们函数来解决这个问题:lean()。代码如下:

Comment.findOne({    id: commentId,},null,{    lean: true}function (err,data) {    if(){        //如果用户点赞        data.isPraise = true;    }else{        //如果用户未点赞        data.isPraise = false;    }});

或者

Comment.findOne({    id: commentId}).lean().exec(function (err,data) {    if(){        //如果用户点赞        data.isPraise = true;    }else {        //如果用户未点赞        data.isPraise = false;    }});

  通过上述方法就可以解决mongoose对返回数据的控制了,你就可以为所欲为了,当然如果不是这种业务,尽量建议少使用,毕竟最好还是使数据符合预先定义的model比较好。

转载地址:http://qeeuo.baihongyu.com/

你可能感兴趣的文章
循环语句的效率
查看>>
VMware 虚拟机克隆 CentOS 6.5 之后,网络配置问题的解决方案
查看>>
Python ( 1 ) ----- 简介
查看>>
[linux基础学习]run level
查看>>
第七周学习总结
查看>>
一步步的教你安装UChome (UChome 安装教程)
查看>>
[DeeplearningAI笔记]序列模型1.5-1.6不同类型的循环神经网络/语言模型与序列生成...
查看>>
P2533 [AHOI2012]信号塔
查看>>
Android电话拨号器(uri格式)与四种设置点击事件的方法
查看>>
java web中对json的使用
查看>>
TYVJ P1051 选课 Label:多叉转二叉&&树形dp(虐心♥)
查看>>
将数据库中提取出来的数据在后台进行分页处理
查看>>
bzoj1034
查看>>
百度地图 鼠标绘制,获取矩形,多边形的顶点经纬度
查看>>
回文树模板
查看>>
struts2之防止表单重复提交
查看>>
【转】Netty系列之Netty并发编程分析
查看>>
cf591d
查看>>
图片存储系统TFS
查看>>
MYSQL备份与恢复
查看>>