2012-11-02 3 views
4

Si j'ai un document imbriqué, comment puis-je mettre à jour un champ dans ce document imbriqué dans Mongoose? J'ai étudié attentivement ce problème en utilisant tout ce que je pouvais trouver, et j'ai même changé mon code de test pour répondre à une question similaire à ce sujet sur Stackoverflow, mais je n'arrive toujours pas à le comprendre. Voici mes schémas et modèles, le code et la sortie de débogage de Mongoose. Je suis incapable de comprendre ce que je fais mal, ici.La mise à jour du document imbriqué Mongoose échoue?

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 



*/ 

Répondre

3

Vous n'utilisez pas les noms de champs corrects dans votre appel B.update. Il devrait être plutôt:

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 fixer votre fonction reset de ne pas appeler son rappel jusqu'à ce que le save termine:

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 
} 
Questions connexes