在学习 mongoose 的时候,碰到一个需要注意的地方。
给查询结果添加额外的属性时,不能直接在这个结果对象上添加属性。原因和解决方案往下看。

假设 User 集合有一个 name 字段:

const User = new mongoose.Schema({ 'name': String });

(添加一些数据)加上它附带的 _id 字段,应该如下:

> User.find().pretty();
//结果
[{"_id": ObjectId("62449223fb0988f6c2cecf3d"),"name": 'wffw'},{"_id": ObjectId("62449223fbca2354d3daf8fca"),"name": 'luyu'},……
]

当我查询结果之后,想要添加一个属性给每一个结果时候,神奇的一幕发生了!

 User.find().then((list) => { list.map((item, index) => {console.log('1---', item);         // (1)item.str = '给item添加一个 str 属性。';  // (2)console.log('2---', item);  // (3)})})
// 结果
1--- [{"_id": ObjectId("62449223fb0988f6c2cecf3d"),"name": 'wffw'},……
]
2--- [{"_id": ObjectId("62449223fb0988f6c2cecf3d"),"name": 'wffw'},……
]

上面 (3) 输出的结果出乎我意料,和 (1) 的结果一模一样,没有发现 str 属性,我的 str 呢?(遇事不决,量子力学?)

这当然不是量子问题。会不会是 这个 item 是只读的,(2)处根本没有赋值成功? 既然如此,那就不直接操作 item ,创建一个新的对象试试(方式一):

 User.find().then((list) => { list.map((item, index) => {let one = {_id: item._id,name: item.name,str: '给item添加一个 str 属性。'}console.log('4---', item); // (4) console.log('5---', mylist);  // (5)})})
// 结果
5--- {"_id": ObjectId("62449223fb0988f6c2cecf3d"),"name": 'wffw',"str": '给item添加一个 str 属性。'}// 果然如此呐,哈哈

那么,,,

到这里你以为就结束了? item 真的是只读的吗?事实就是如此的吗?

(真相~ 真香~)

听说过 getOwnPropertyDescriptors() 吧,打印一下 item的属性描述符:

 User.find().then((list) => { list.map((item, index) => {item.str = '这是一个新的属性';console.log('6---', item)   // (6) console.log('list[' + index + ']---', Object.getOwnPropertyDescriptors(item));  // (7)})})
// 结果
//毋庸置疑,(6) 打印的结果里没有 str。

(7) 打印的结果 会是什么呢?如下:

// (7) 打印的结果:取其中一个:
list[0]--- {'$__': {value: InternalCache {activePaths: [StateMachine],strictMode: true,skipId: true,selected: {},fields: {},exclude: null,_id: new ObjectId("62449223fb0988f6c2cecf3d")},writable: true,enumerable: true,configurable: true},'$isNew': {value: false,writable: true,enumerable: true,configurable: true},_doc: {value: {_id: new ObjectId("62449223fb0988f6c2cecf3d"),name: 'wffw',__v: 0},writable: true,enumerable: true,configurable: true},str: { value: '这是一个新的属性', writable: true, enumerable: true, configurable: true }
}

前两个属性("$__"、"$isNew")忽略,仔细看最后两个属性:_doc 里的属性才是 我们cosole.log(item) 的结果!str 并不是没有添加成功,item 并不是只读的!

Emm……#?!$@*……

现在知道了吧,find().then() 或者 findOne().then() 得到的结果,是有一层封装,在获取这个结果的时候,会自动解封,但是 在自己添加属性的时候,不会自动解封。官方说法:

Mongoose models provide several static helper functions for CRUD operations. Each of these functions returns a mongoose `Query` object.

Mongoose模型为CRUD 操作提供了几个静态辅助函数。这些函数中的每一个都返回一个 mongooseQuery对象。

所以,除了(方式一),还有一种方式,赋给 item._doc (方式二) :

 User.find().then((list) => { list.map((item, index) => {console.log('8---', item); // (8) item._doc.str = '给item添加一个 str 属性。';console.log('9---', item); // (9) })})
// (8) 略
// (9) 结果:
1--- [{"_id": ObjectId("62449223fb0988f6c2cecf3d"),"name": 'wffw',"str": '给item添加一个 str 属性。'},……
]

舒服了。

总结: 方式一 和方式二 都可以,推荐方式一,因为这不需要额外知道"_doc"。

(官网似乎也没有怎么提到_doc,是我菜了)

searching for _doc

以上。

给mongoose find()/findOne()查询的结果添加额外的属性相关推荐

  1. Statement接口实现查询数据、添加数据

    本文介绍了Statement接口实现查询数据.添加数据.在JDBC的基本应用中,介绍了使用Statement接口查询和添加数据的步骤.重点在于使用getConnection()方法来连接数据库,创建S ...

  2. mysql自定义序号_MySQL数据库之在mysql中给查询的结果添加序号列

    本文主要向大家介绍了MySQL数据库之在mysql中给查询的结果添加序号列 ,通过具体的内容向大家展现,希望对大家学习MySQL数据库有所帮助. 一:第一种: select   (@i:=@i+1)  ...

  3. mysql创建表对经常要查询的列添加索引或者组合索引

    创建表的时候对经常要查询的列添加索引或者组合索引 索引直接影响后面的查询性能,尤其是数据量越大的时候,影响越明显.作为一个从事DBA生涯超过5年的DBA,遇到过无数次由于没有添加索引,导致的线上故障, ...

  4. Salesforce系列(六):Salesforce Apex基础SOQL查询和数据添加!

    Salesforce系列(六):Salesforce Apex基础SOQL查询和数据添加! 前言 今天博主将为大家分享:Salesforce系列(六):Salesforce Apex基础SOQL查询和 ...

  5. Salesforce系列(五):Salesforce Apex基础SOSL查询和数据添加!

    Salesforce系列(五):Salesforce Apex基础SOSL查询和数据添加! 前言 今天博主将为大家分享:Salesforce系列(五):Salesforce Apex基础SOSL查询和 ...

  6. mysql怎么给数据加序号_MySQL数据库之在mysql中给查询的结果添加序号列

    本文主要向大家介绍了MySQL数据库之在mysql中给查询的结果添加序号列 ,通过具体的内容向大家展现,希望对大家学习MySQL数据库有所帮助. 一:第一种: select   (@i:=@i+1)  ...

  7. 一个可以添加商品、查询商品的程序,登录成功的话,再去操作,添加、查询商品,添加商品也是写在文件里面...

    #写一个可以添加商品.查询商品的这么程序#1.先登录,登录的用户名和密码都是写在文件里面的#1.读文件.字符串分割#2.登录成功的话,再去操作,添加.查询商品,添加商品也是写在文件里面#1.读写文件, ...

  8. Python程序设计实例:可查询修改、添加、测验、朗读的英语词典

    前言 利用Python设计一款可以用查询.朗读.添加.测试的英语词典小程序是非常方便的 主要功能 查询.添加.修改.测验.朗读.退出 主要思路 其数据类型应为字典类型,导入英语词典文本文档(dict. ...

  9. SpringBoot+jquery实现post提交表单并添加隐藏域属性完成编辑功能

    场景 如下页面编辑时: 在选择归属机构时会出现树形结构,所以在提交时需要额外提交一些信息,可以在form中使用input的隐藏域进行存值. 实现 html代码 <div class=" ...

最新文章

  1. Resource interpreted as Stylesheet but transferred with MIME type application/x-css
  2. 2.2.1 处理机调度的概念和层次
  3. 减负提质的新命题下,网易云信如何为课后服务升级?
  4. P5445-[APIO2019]路灯【set,树状数组套线段树】
  5. C++ 一键关闭屏幕
  6. hadoop HA 之 QJM
  7. iText生成pdf详解
  8. BlockingQueue的核心方法
  9. Spring Cloud Hystrix - 服务容错
  10. allennlp手动安装教程
  11. 基于遗传算法(deap库)的一元函数寻优代码详解
  12. 谋定而后动,理想不相信热血
  13. CD Linux启动盘,CDlinux硬盘启动制作方法。CDlinux硬盘怎样启动制作?
  14. 1076: 三位数求解-python
  15. 苹果apple账号授权登录第三方APP
  16. Redis中的数据类型及其应用场景
  17. 阿里云服务器数据迁移
  18. 电脑安装两个jdk版本无法切换 同时安装JDK8和JDK16 配置JAVA_HOME为JDK8但 java 和 javac 版本都是16
  19. 工业机器人实训实验平台
  20. 人事管理系统是什么?HR系统有什么用?

热门文章

  1. 几个离散混沌映射系统(混沌函数)
  2. 数字图像处理中的Region与XLD
  3. PC(Ubuntu)和树莓派实现无秘ssh
  4. SAP增强 BADI屏幕增强实例(MIGO增加分页签)
  5. [CC2642R1][VSCODE+Embedded IDE+Cortex-Debug] TI CC2642R1 快速搭建VsCode开发环境
  6. matlab 股,用Matlab来做三种股票的投资模型
  7. 大学在校 计算机考试,大学必考证书 | 计算机考试报名要开始啦!
  8. 后端面试之系统设计-短网址(Short URL)服务怎么设计?
  9. Ubuntu子系统安装GPGPU-SIM(附相关文件)
  10. 洛谷题单1-7 搜索题解