不正确的子文档被更新?

我有一个包含一系列子文档的Schema,我只需要更新其中的一个。 我使用子文档的ID做一个findOne ,然后将返回的数组中的位置0的子文档的响应减less。

不pipe我做什么,我只能得到父文档中的第一个子文档来更新,即使它应该是第二,第三等。只有第一个子文档被更新,不pipe是什么。 据我所知它应该工作,但我不是一个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时,就是说它已经更新了正确的logging,即使它实际上更新了第一个子文档,而不是它所说的那个。

模式以防万一:

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

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

另外,这是一个错字和req.body.file应该是req.body.filename? 我会认为这是例子。

另外,我还没有对此做过严肃的testing,但是如果你指定你的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 } 

mongoose不理解位置投影操作符返回的文档。 它始终在位置上更新一系列子文档,而不是通过id。 您可能有兴趣查看mongoose正在构build的实际查询 – 使用mongoose.set('debug', true)

你必须得到整个数组,或者build立自己的MongoDB查询并绕过mongoose。 我会build议前者; 如果拉动整个arrays会导致性能问题,那么最好让每个子文档都成为顶层文档 – 无边界增长的文档会变得有问题(至less因为Mongo文档大小有限) 。

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

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