1

我有一个包含一组子文档的架构,我只需要更新其中一个。我findOne使用子文档的 ID 执行操作,然后在返回的数组中的位置 0 处减少对该子文档的响应。

不管我做什么,我只能更新父文档中的第一个子文档,即使它应该是第二个、第三个等。无论如何,只有第一个被更新。据我所知,它应该可以工作,但我不是 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 时,它也表示它更新了正确的记录,即使它实际上更新了第一个子文档而不是它所说的那个。

架构以防万一:

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);
4

3 回答 3

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
}
于 2013-09-25T10:00:28.477 回答
0

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

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

于 2013-09-25T06:43:20.730 回答
0

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

db.Template.update( { "pages._id": page }, { $set: { "pages.$.body" : body } } )
于 2013-09-25T07:20:58.537 回答