2012-11-02 191 views
4

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

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

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 



*/ 

回答

3

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

你也应该解决您的reset功能,直到save完成不调用它的回调:

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 
}