Mongoose嵌套文件更新失败?

如果我有一个嵌套的文档,如何更新Mongoose中的嵌套文档中的字段?

我仔细研究了这个问题,使用了我可以find的所有东西,甚至改变了我的testing代码,以便在Stackoverflow上匹配类似的回答问题,但是我仍然无法弄清楚。 这里是我的模式和模型,代码和Mongoosedebugging输出。 我无法理解我在做什么错,在这里。

var mongoose = require('mongoose') , db = mongoose.createConnection('localhost', 'test') , assert = require("node-assert-extras"); var Schema = mongoose.Schema; var ObjectId = Schema.ObjectId; db.once('open', function () { // yay! }); mongoose.set('debug', true); var PDFSchema = new Schema({ title : { type: String, required: true, trim: true } }) var docsSchema = new Schema({ PDFs : [PDFSchema] }); var A = db.model('pdf', PDFSchema); var B = db.model('docs', docsSchema); function reset(cb) { B.find().remove(); // create some data with a nested document A var newA = new A( { title : "my title" }) var newB = new B( { PDFs: newA}); newB.save(); cb(); } function test1( ) { reset(function() { B.findOne({}, 'PDFs', function(e,o) { console.log(o); pdf_id = o.PDFs[0]._id; console.log("ID " + pdf_id); B.update( { 'pdfs.pdf_id': pdf_id }, { $set: { 'pdfs.$.title': 'new title' }}, function (err, numAffected) { if(err) throw err; assert.equal(numAffected,1); //KA Boom! } ); }); }); } test1(); /* $ node test2.js Mongoose: docs.remove({}) {} Mongoose: docs.findOne({}) { fields: { PDFs: 1 }, safe: true } Mongoose: docs.insert({ __v: 0, PDFs: [ { _id: ObjectId("50930e3d0a39ad162b000002"), title: 'my title' } ], _id: ObjectId("50930e3d0a39ad162b000003") }) { safe: true } { _id: 50930e3d0a39ad162b000003, PDFs: [ { _id: 50930e3d0a39ad162b000002, title: 'my title' } ] } ID 50930e3d0a39ad162b000002 assert.js:102 throw new assert.AssertionError({ ^ AssertionError: 0 == 1 */ 

您在B.update调用中没有使用正确的字段名称。 应该是这个,而不是:

 B.update( { 'PDFs._id': pdf_id }, // <== here { $set: { 'PDFs.$.title': 'new title' // <== and here }}, function (err, numAffected) { if(err) throw err; assert.equal(numAffected,1); } ); 

您还应该修复您的resetfunction,直到save完成后才能调用其callback函数:

 function reset(cb) { B.find().remove(); // create some data with a nested document A var newA = new A( { title : "my title" }) var newB = new B( { PDFs: newA}); newB.save(cb); // <== call cb when the document is saved }