我正在尝试对从mongoose / MongDB查询返回的数据数组进行一些修改。但是,我似乎无法对数组进行任何更改。我错过了一些明显的东西吗?
function stdSend(err, data, res){
if(err){
console.log(err);
res.send(err);
}else{
console.log('rows returned: ' + data.length);
for(var rep=0;rep<data.length;rep++){
var foo = new Date(data[rep].timestamp);
console.log(Object.isFrozen(data[rep])); <- false
console.log(Object.isSealed(data[rep])); <- false
data[rep].test = 'test'; <- test not added to data[rep]
data[rep].timestamp = foo; <- timestamp not modified
console.dir(data[rep]);
}
//console.log(data);
res.send(data);
}
}
正在从Mongoose .exec函数调用stdSend作为回调。回调正常,我将数据传送到Express中的res.send后数据会进入浏览器。但是,我希望通过在发送之前将data [] .timestamp值转换为标准的datetime值来进行一些快速的bug测试。
但是,我试图更改数据值的所有内容都失败了。数据[rep] .test ='test'无法向数据添加测试属性,并且修改时间戳的尝试也失败。两者都是冷冻和isSealed返回虚假。
有什么想法在这里发生了什么?
编辑:我认为我在这里问的问题有些混乱。我不是将数据写入数据库。这是我尝试修改的数据库查询返回的对象数组。返回的对象如下:
[ { name: 'scishow',
timestamp: 1380154343818,
funding: 42,
subs: 3500 },
{ name: 'scishow',
timestamp: 1380240748329,
funding: 42,
subs: 3520 },
{ name: 'scishow',
timestamp: 1380327152521,
funding: 42,
subs: 3554 },
{ name: 'scishow',
timestamp: 1380413558026,
funding: 43,
subs: 3579 },
{ name: 'scishow',
timestamp: 1380585807946,
funding: 43,
subs: 3638 },
{ name: 'scishow',
timestamp: 1384300959056,
funding: 52,
subs: 5 },
{ name: 'scishow',
timestamp: 1384560752617,
funding: 53,
subs: 5 },
{ name: 'scishow',
timestamp: 1384646717448,
funding: 53,
subs: 5 },
{ name: 'scishow',
timestamp: 1384819280960,
funding: 53,
subs: 5 },
{ name: 'scishow',
timestamp: 1385251243369,
funding: 53,
subs: 5753 },
{ name: 'scishow',
timestamp: 1385338257810,
funding: 53,
subs: 5779 } ]
如果data
是Mongoose查询的结果,那么它不是普通JS对象的数组,而是一个文档实例数组。它们可能看起来像正确的JS对象,但你不能这样对待它们。
您需要先将这些文档转换为正确的JS对象,然后才能更改它们:
for (var rep = 0; rep < data.length; rep++) {
var doc = data[rep].toObject();
var foo = new Date(doc.timestamp);
doc.test = 'test';
doc.timestamp = foo;
console.dir(doc);
}
或者,您可以将{ strict: false }
添加到您的架构中(如@HenryLeu建议的那样)并在文档上使用.set()
来添加属性:
data[rep].set('test', 'test');
或者不更改您的架构:
data[rep].set('test', 'test', { strict: false });
在您的mongoose架构定义代码中。尝试使用选项strict: false
来启用设置和获取未定义的架构字段。默认情况下,strict
是true
。
var thingSchema = new Schema({name: String, ...}, { strict: false});
@robertklep的答案对我很有帮助,但是如果你试图用EJS渲染文档,你刚刚使用.set()
附加的关键:值将返回undefined
,因为EJS接收mongo记录作为文档而不是JSON。
因此,如果您不是在寻找Mongo文档而只是JSON,那么当与.lean()
一起使用时,您可以使用.exec()
返回JSON对象而不是Mongo文档。
YOUR_MODEL.find()
.lean().exec((err, data) => {
if(err) throw err;
//Assuming data will return something like [{myKey: val}, {myKey: val}]
data.forEach((obj, idx) => {
data[idx].myKey = 'alterValue';
});
});