0

我在猫鼬.find查询后这样做:

data2[0].videos[temp].markModified('fakeName');
data2[0].save(function(err,product,numberAffected){
    if(err){
        console.log("error saving manifest")
        console.log(err);
        var back={success:false, reason:err};
        callback(back);
        return;
    }
    if(numberAffected>=1){
        console.log("manifest saved",product.videos[temp]);
        var back={success:true};
        callback(back);
        return;
    }else{
        console.log("nothing saved");
        callback({success:false});
        return;
    }
});

打印这个:

  manifest saved { fakeName: 'devrenameTest',
  name: 'bkdyZVb--',
  version: 1,
  dateCreated: 1406846165732,
  dateUpdated: 1406846165732,
  vidLoc: '[url removed]',
  thumbLoc: '[url removed]',
  author: '53a47a469c52c9d83a2d71d9',
  _id: 53dac4d533c061dd0b000007,
  sharedWithGroups: [],
  sharedWith: [],
  tags: [] }

所以它似乎工作对了吗?

但是,如果我查看我的数据库,我会看到其中的子文档videos仅由一个fakeName字段组成,而我正在修改的对象没有fakeName字段。

这是怎么回事?

我将那里的第一行改为

data2[0].markModified('videos');

这似乎解决了它。

我仍然会根据对正在发生的事情的解释接受答案。

4

1 回答 1

0

由于它是无模式类型,因此您可以将值更改为您喜欢的任何其他值,但 Mongoose 失去了自动检测和保存这些更改的能力。要“告诉”Mongoose Mixed 类型的值已更改,请调用文档的 .markModified(path) 方法,将路径传递给刚刚更改的 Mixed 类型。

因此,在具有混合类型(基本上没有验证)的嵌入式文档或数组(没有架构)中,您必须明确告诉 mongoose 在保存之前已修改特定字段。

查看架构类型并搜索markModified. API 文档没有提供信息。

至于你的例子,

 data2[0].markModified('videos')

就足够了。我假设 data2[0] 是一个 mongoDB 文档。您只需要提供发生更改的嵌入文档(混合模式)的路径。不是被改变的最内层。

例如,如果我有一个模式 - 模型 Artist, { name:String, albums: [{}] } 如果有文档 doc

{name:'artist1',
      albums:[
        {name:'album1',
         songs:[{name:'song1'},
                {name:'song2'},
                {name:'song3'}
               ]
        },
        {name:'album2',
         songs:[{name:'song4'},
                {name:'song5'},
                {name:'song6'}
               ]
       }
           ]
}

当我进行修改时

doc.albums[1].songs[2]='song25'

我只需要指定混合类型的最外层路径。

doc.markModified('albums')
doc.save();

即使相册数组有另一层嵌套,markModified调用也将保持不变

于 2014-08-03T02:04:23.257 回答