保存subdoc时mongodb意外行为

时间:2014-07-31 22:48:50

标签: javascript node.js mongodb mongoose subdocument

我在mongoose .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');

这似乎解决了这个问题。

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

1 个答案:

答案 0 :(得分:0)

  

由于它是无模式类型,您可以将值更改为您喜欢的任何其他值,但Mongoose无法自动检测并保存这些更改。要告诉" Mongoose表示混合类型的值已更改,请调用文档的.markModified(path)方法,将路径传递给刚刚更改的Mixed类型。

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

查看the schema types并搜索markModifiedAPI docs没有提供信息。

至于你的例子,

 data2[0].markModified('videos')

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

例如,如果我有一个架构 - 模型艺术家,      {          名称:字符串,          专辑:[{}]      } 如果有文档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调用也将保持不变