La mise à jour du document nested Mongoose a échoué?

Si j’ai un document nested, comment puis-je mettre à jour un champ de ce document nested dans Mongoose?

J’ai soigneusement étudié ce problème en utilisant tout ce que je pouvais trouver et ai même modifié mon code de test pour qu’il corresponde à une question similaire à ce sujet ici sur Stackoverflow, mais je suis toujours incapable de comprendre cela. Voici mon schéma et mes modèles, le code et la sortie de débogage de Mongoose. Je suis incapable de comprendre ce que je fais mal, ici.

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: Ssortingng, required: true, sortingm: 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 */ 

Vous n’utilisez pas les noms de champs corrects dans votre appel B.update . Ce devrait être ceci à la place:

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

Vous devez également corriger votre fonction de reset pour ne pas appeler son rappel tant que la save n'est pas terminée:

 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 }