Mongoose嵌入式文档更新

时间:2011-11-03 21:31:27

标签: javascript mongodb node.js mongoose

我的嵌入式文档更新存在问题。

我定义的架构:

var Talk = new Schema({
    title: {
        type: String,
        required: true
    },
    content: {
        type: String,
        required: true
    },
    date: {
        type: Date,
        required: true
    },
    comments: {
        type: [Comments],
        required: false
    },
    vote: {
        type: [VoteOptions],
        required: false
    },
});

var VoteOptions = new Schema({
    option: {
        type: String,
        required: true
    },
    count: {
        type: Number,
        required: false
    }
});

现在,我想使用给定的vote.count++ ID和Talk ID更新VoteOption。我有以下功能来完成这项工作:

function makeVote(req, res) {

    Talk.findOne(req.params.id, function(err, talk) {
        for (var i = 0; i < talk.vote.length; i++) {
            if (talk.vote[i]._id == req.body.vote) {
                talk.vote[i].count++;

            }
        }
        talk.save(function(err) {
            if (err) {
                req.flash('error', 'Error: ' + err);
                res.send('false');
            } else {
                res.send('true');
            }
        });
    });
}

一切都在执行,我回到res.send('true'),但是计数值不会改变。

当我做了一些console.log时,我发现它改变了值,但talk.save只是没有将其保存在db中。

此外,我对于查找_id嵌入式文档的周期非常不满意。在mongoose文档中,我读到了talk.vote.id(my_id),但这给了我一个没有id函数的错误。

2 个答案:

答案 0 :(得分:19)

更新Mixed类型(似乎不是基本类型,因此也包含嵌入文档)时,必须在文档上调用.markModified。在这种情况下,它将是:

talk.markModified("vote"); // mention that `talk.vote` has been modified

talk.save(function(err) {
    // ...
});

希望这可以帮助将来的某个人,因为我很快就找不到答案。


Reference:

  

...... Mongoose失去了自动检测/保存这些更改的能力。要“告诉”Mongoose混合类型的值已更改,请调用文档的.markModified(path)方法,将路径传递给刚刚更改的混合类型。

答案 1 :(得分:0)

这是因为您试图在回调之前保存您的谈话对象,其中已经触发了增量计数。另外,您确定要实例化您的Talk模式吗?例如:

var talk = new Talk();

但是,如果您只想增加计数变量,那么mongo支持您可能觉得有用的原子就地更新:

talk.find( { _id : req.body.vote }, { $inc: { count : 1 } } );

看看: http://www.mongodb.org/display/DOCS/Updating#Updating-%24inc