4

If I have a nested document, how can I update a field in that nested document in Mongoose?

I carefully researched this problem using everything available I could find, and even changed my test code to match a similar answered question about this here on Stackoverflow, but I am still unable to figure this out. Here are is my Schema and Models, the code, and the Mongoose debug output. I am unable to understand what I am doing wrong, here.

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 */ 

1 Answer 1

3

You're not using the correct field names in your B.update call. It should be this instead:

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

You should also fix your reset function to not call its callback until the save completes:

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 } 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.