3

更新保存在 mongodb 记录中的数组中的值的最佳方法是什么?目前,我正在尝试这种方式:

Record.find({ 'owner': owner}, {}, {sort: { date: -1 }}, function(err, record){
    if(!err){
        for (var i = 0; i < record[0].array.length; i++){
            record[0].array[i].score = 0;

            record[0].array[i].changed = true;

            record[0].save();
        }
    }
 });

架构如下所示:

var recordSchema = mongoose.Schema({
    owner: {type: String},
    date: {type: Date, default: Date.now},
    array: mongoose.Schema.Types.Mixed
});

现在,我可以看到数组更新了,保存时没有错误,但是当我再次查询数据库时,数组还没有更新。

4

2 回答 2

14

如果您在此处解释您的意图,因为将属性命名为“数组”并没有传达其目的,这将有所帮助。我猜从您的代码中您希望将那里的每个项目的分数设置为零。请注意,您的保存当前被忽略,因为您只能保存顶级 mongoose 文档,而不能保存嵌套文档。

数组上的某些查找和修改操作可以通过使用数组更新运算符(如$push$addToSet等)的单个数据库命令来完成。但是我看不到任何运算符可以直接在单个操作中进行所需的更改。因此,我认为您需要找到您的记录,更改数组日期并保存它。(注意findOne是一个方便的功能,如果您只关心第一个匹配项,您可以使用,这对您来说似乎就是这种情况)。

Record.findOne({ 'owner': owner}, {}, {sort: { date: -1 }}, function(err, record){
    if (err) {
       //don't just ignore this, log or bubble forward via callbacks
       return;
    }
    if (!record) {
        //Record not found, log or send 404 or whatever
        return;
    }
    record.array.forEach(function (item) {
        item.score = 0;
        item.changed = true;
    });
    //Now, mongoose can't automatically detect that you've changed the contents of 
    //record.array, so tell it
    //see http://mongoosejs.com/docs/api.html#document_Document-markModified
    record.markModified('array');
    record.save();        
 });
于 2013-07-25T18:57:32.697 回答
3

如果您有一个文档的猫鼬对象,您当然可以像问题中那样更新数组,并使用以下警告

这实际上是一个猫鼬陷阱。Mongoose 无法跟踪混合数组的变化,必须使用 markModified:

doc.mixed.type = 'changed';
doc.markModified('mixed.type');
doc.save() // changes to mixed.type are now persisted
于 2014-04-03T09:13:03.243 回答