我无法在Node中修改数组

时间:2013-11-26 08:35:37

标签: node.js mongodb mongoose

我试图对从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 =&#39; test&#39;无法向数据添加测试属性,并且修改时间戳的尝试也失败。两者都是冷冻和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 } ]

3 个答案:

答案 0 :(得分:4)

如果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 });

答案 1 :(得分:0)

在你的mongoose架构定义代码中。尝试使用选项strict: false来启用设置和获取未定义的架构字段。默认情况下,stricttrue

var thingSchema = new Schema({name: String, ...}, { strict: false});

请参考mongoose docs about strict option

答案 2 :(得分:0)

@robertklep回答对我有帮助但是如果你试图用EJS渲染文档,那么你刚刚使用.set()追加的关键:值将返回undefined,因为EJS收到mongo记录作为文档,而不是JSON。

因此,如果您不是在寻找Mongo文档而只是JSON,那么当与.exec()一起使用时,可以使用.lean()将返回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';
  });
});