4

如果我有一个嵌套文档,如何在 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



*/
4

1 回答 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
}
于 2012-11-02T00:52:44.843 回答