Mongoose:无法使用$ addToSet或$ push将新对象添加/推送到数组

Ang*_*ner 7 mongoose mongodb node.js

我使用Nodejs,Hapijs和Mongoose.

我的架构和模型如下.

var schema = {
    name: {
        type: String,
        required: true
    },
    lectures: {}
};

var mongooseSchema = new mongoose.Schema(schema, {
    collection: "Users"
});
mongoose.model("Users", mongooseSchema);
Run Code Online (Sandbox Code Playgroud)

出于某种原因,我需要将"讲座"作为混合类型.

在保存/创建文档时,我创建了一个嵌套属性lectures.physics.topic [],其中topic是一个数组.

现在,我正在尝试使用$ addToSet或$ push将新对象添加/推送到"lectures.physics.topic".

userModel.findByIdAndUpdateAsync(user._id, {
    $addToSet: {
        "lectures.physics.topic": {
            "name": "Fluid Mechanics",
            "day": "Monday",
            "faculty": "Nancy Wagner"
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

但该文件根本没有得到更新.我也试过使用$ push.没有任何效果.可能是什么问题呢?

我试图使用mongoclient的另一种方法,直接更新数据库.它的工作原理请找到下面的代码

db.collection("Users").update({
   "_id": user._id
 }, {
 $addToSet: {
        "lectures.physics.topic": {
            "name": "Fluid Mechanics",
            "day": "Monday",
            "faculty": "Nancy Wagner"
        }
    }
 }, function(err, result) {
   if (err) {
       console.log("Superman!");
       console.log(err);
       return;
   }
 console.log(result);     
 });
Run Code Online (Sandbox Code Playgroud)

每次请求被命中时我都必须启动mongo客户端.这不是一个可行的解决方案.

chr*_*dam 3

Mongoose 失去了自动检测和保存对混合类型所做的更改的能力,因此您需要通过调用将路径传递给您.markModified(path)刚刚更改的混合类型的文档方法来“告诉”它混合类型的值已更改:

doc.mixed.type = 'changed';
doc.markModified('mixed.type');
doc.save() // changes to mixed.type are now persisted 
Run Code Online (Sandbox Code Playgroud)

在您的情况下,您可以使用findById()方法来进行更改,方法是调用addToSet()主题数组上的方法,然后触发该save()方法来保存更改:

userModel.findById(user._id, function (err, doc){
    var item = {
        "name": "Fluid Mechanics",
        "day": "Monday",
        "faculty": "Nancy Wagner"
    };
    doc.lectures.physics.topic.addToSet(item);
    doc.markModified('lectures');
    doc.save() // changes to lectures are now persisted 
});
Run Code Online (Sandbox Code Playgroud)