mongoose 对象的属性添加和修改
一、前言
今天在使用mongoose的时候遇到了一个问题,就是DB的日期格式是utc的,在传到前端显示的时候需要处理一下,本来以为简单使用moment处理一下就可以了,没想到遇到了不少问题,不管我如何修改都不起作用。
二、具体场景
这里的datas是从DB查询的,从上面可以看出日期是utc。
处理之前本来以为如上处理一下就可以了,可是执行这行代码并没有效果,如下。
处理之后弄了将近一个多小时,最后终于解决了,即我没有注意到datas是mongoose对象,它并不是一个纯js对象,不能正常的给它修改属性。
解决方法即是将它修改成一个正常的js对象即可。
// 将mongoose对象转换为js对象
datas = _.map(datas,data=>_.pick(data,_.map(fields,'name')));
最后完美解决。
00003.png三、延伸
实话说上面的解决方案是我自己试出来的,并不一定完全正确,是不是mongoose对象就一定不能修改属性呢?还有删除和添加属性呢?需要验证!
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/test');
const Cat = mongoose.model('Cat', { name: String });
const kitty = new Cat({ name: 'Zildjian' });
kitty.save().then(() => {
console.log('meow')
// 查询
Cat.find().then(cats => {
for (const cat of cats) {
cat['name'] = '张三';
cat['age'] = 12 ;
}
console.log(cats);
})
});
如上输出
[ { _id: 5bddc6a6db4414761eb91794, name: '张三', __v: 0 },
{ _id: 5bddc7e6ebaab877470bffa1, name: '张三', __v: 0 },
{ _id: 5bddc824c3d82877b712c6f1, name: '张三', __v: 0 },
{ _id: 5bddc82af0935777b81cf12d, name: '张三', __v: 0 },
{ _id: 5bddc84d2a9a4277e6ed7270, name: '张三', __v: 0 },
{ _id: 5bddc86d02ddcd78189e7e76, name: '张三', __v: 0 } ]
由于我运行了多次,所以会有多条记录,这不是重点,可以看到,我们是可以修改mongoose对象的属性,但是不能增加mongoose对象的属性。由此可以看到我们在上面的总结有误。于是我想,是不是可能因为类型当原因?于是我就有了如下代码:
const mongoose = require('mongoose');
const moment = require('moment');
mongoose.connect('mongodb://localhost/test');
let date = '2018-07' ;
let other = '2020-07';
const Cat = mongoose.model('Cat', { name: String,issue:Date });
const kitty = new Cat({ name: 'Zildjian',issue:moment(date).toDate() });
kitty.save().then(() => {
console.log('meow')
// 查询
Cat.find().then(cats => {
for (const cat of cats) {
cat['name'] = 111 ;
cat['issue'] = '111';
cat['age'] = 12 ;
}
console.log(cats);
})
});
输出如下:
[{ _id: 5bddd01e1ff8987f60b2b74c,
name: '111',
issue: 0110-12-31T15:54:17.000Z,
__v: 0 },
{ _id: 5bddd0243a05067f68f76cad,
name: '111',
issue: 0110-12-31T15:54:17.000Z,
__v: 0 } ]
由此可知,我们给issue设置值它确实改变了,不过因为它是date类型的,它又被强制转换了date类型了。而为什么name没有变化呢,是因为它隐藏转换了。这就解释了我前面的问题为什么我的日期设置无效的问题了。也回答了一个问题mongoose对象可以修改,那么从上面的例子也可以看出mongoose是不可以添加属性的。那么如果业务需要的话如何实现呢?
四、mongoose对象添加属性
首先我们要知道为什么添加属性无效?因为我们使用Mongoose取到的数据的结构是要依赖于我们定义的schema结构的。增加的属性在schema中没有定义,因此添加不能起效果,那么解决方式就来了,既然是因为schema没有才导致不能添加的,那么就在schema添加该属性即可;还有一种方案,即既然mongoose不能添加属性,那么我们可以创建一个新对象,在新对象添加属性即可。我在第二节处理的时候就是采用第二种方式,因为我在schema中定义的日期是date,可是前端只需要显示YYYY-MM的字符串就可以了,那么我直接用moment格式成字符串可能没有效果,于是我就创建一个新对象,在新对象上操作即可完美解决。
五、总结
这个其实是很小的一个问题,不过细节决定成败,一点一滴做起吧。
项目地址:https://github.com/MrLW/mongoose-study/blob/master/demo01.js
欢迎关注公众号
码农求道