更新不正确的子文档?

时间:2013-09-25 06:34:51

标签: node.js mongodb mongoose

我有一个包含子文档数组的Schema,我需要更新其中一个。我使用子文档的ID执行findOne,然后将响应减少到返回数组中位置0处的子文档。

无论我做什么,我只能在父文档中获取第一个子文档进行更新,即使它应该是第2个,第3个等等。只有第一个子文档无论如何都会更新。据我所知它应该工作,但我不是MongoDB或Mongoose专家,所以我在某处显然是错的。

 var template = req.params.template;
  var page = req.params.page;
  console.log('Template ID: ' + template);

  db.Template.findOne({'pages._id': page}, {'pages.$': 1}, function (err, tmpl) {
    console.log('Matched Template ID: ' + tmpl._id);
    var pagePath = tmpl.pages[0].body;
    if(req.body.file) {
      tmpl.pages[0].background = req.body.filename;
      tmpl.save(function (err, updTmpl) {
        console.log(updTmpl);
        if (err) console.log(err);
      });
      // db.Template.findOne(tmpl._id, function (err, tpl) {
      //   console.log('Additional Matched ID: ' + tmpl._id);
      //   console.log(tpl);
      //   tpl.pages[tmpl.pages[0].number].background = req.body.filename;
      //   tpl.save(function (err, updTmpl){
      //     if (err) console.log(err);
      //   });
      // });
    }

在控制台中,所有ID都匹配正确,即使我返回updTmpl,它也说它更新了正确的记录,即使它实际更新了第一个子文档而不是它所说的那个。< / p>

模式以防万一:

var envelopeSchema = new Schema({
  background: String,
  body: String
});

var pageSchema = new Schema({
  background: String,
  number: Number,
  body: String
});

var templateSchema = new Schema({
  name: { type: String, required: true, unique: true },
  envelope: [envelopeSchema],
  pagecount: Number,
  pages: [pageSchema]
});
templateSchema.plugin(timestamps);

module.exports = mongoose.model("Template", templateSchema);

3 个答案:

答案 0 :(得分:1)

首先,如果您需要设置req.body.file以便执行更新,我建议您在运行查询之前检查它。

另外,是不是错字和req.body.file应该是req.body.filename?我会假设它是为了这个例子。

此外,我还没有对此进行认真测试,但我相信如果你指定Template._id,你的通话会更有效率:

var template_id = req.params.template,
    page_id = req.params.page;

if(req.body.filename){

    db.Template.update({_id: template_id, 'pages._id': page_id},
        { $set: {'pages.$.background': req.body.filename} },
        function(err, res){
            if(err){
                // err
            } else {
                // success
            }
        });
} else {
    // return error / missing data
}

答案 1 :(得分:0)

Mongoose不理解使用位置投影运算符返回的文档。它总是更新一个子文档数组位置,而不是id。您可能有兴趣查看mongoose正在构建的实际查询 - 使用mongoose.set('debug', true)

你必须要么获得整个数组,要么构建自己的MongoDB查询并绕过mongoose。我会建议前者;如果拉动整个数组会导致性能问题,你可能最好将每个子文档作为顶级文档 - 无限制增长的文档会成为问题(至少因为Mongo有一个硬文档大小限制)

答案 2 :(得分:0)

我不熟悉mongoose,但Mongo更新查询可能是:

db.Template.update( { "pages._id": page }, { $set: { "pages.$.body" : body } } )