猫鼬使用save()方法不会保存文档

时间:2018-07-30 12:56:29

标签: javascript node.js mongodb mongoose

我有这个模式:

var UserSchema = mongoose.Schema({
    analytic: {
      type: Object, 
      default: {
        today:[],
        weekly:[],
        monthly:[],
        yearly:[],
        allTime:[]
      }
    }
});

let User = mongoose.model("bloger", UserSchema);
module.exports = {User};

我正在尝试将一些数据保存到这样的数组之一中:

    User.findOne({username:username}, (e, user) => {
        if (e) {
            res.send('error fetching post')
        }
        else if (!user) {
            res.send('no user found')
        }
        else if (user) {
            user.analytic.today.push(req.body.visitor) // push the data object to the array
            user.save((e, doc) => {
                if (e) {
                    res.send(e)
                } 
                if (doc) {
                     console.log('user saved')
                    res.send(doc)
                }
            })
        }
    })
}) 

我在doc上获得了save()对象,而不是e上的对象,所以我虽然应该保存它,但事实并非如此。

2 个答案:

答案 0 :(得分:2)

在此之前,我遇到了类似的问题,因为我没有定义新模型,而只是传递了JSON对象。

代替保存对象,您需要创建一个新模型并将其保存。

尝试创建一个新模型,如下所示将保存内容传递到其中;

var newUser = new User(user);
newUser.save((e, doc) {
    if (e) {
       res.send(e)
    } 
    if (doc) {
        console.log('user saved')
        res.send(doc)
    }
});

确保脚本中需要用户模型。

答案 1 :(得分:0)

对不在您架构中的对象进行深度修改使Mongoose忽略了这些更改,从而阻止了它知道要保存的内容(以及进行了有效的原子更新)。最终结果是,当调用.save时,Mongoose认为没有任何修改,因此什么也没做。

在您的特定情况下,您有两个选择:

1。将analytics子数组添加到架构中

这是最好的选择,可以更好地控制所有内容:

const UserSchema mongoose.Schema({
  analytic: {
    today: [{}],
    weekly: [{}],
    monthly: [{}],
    yearly: [{}],
    allTime: [{}],
  }
});

有了这些,猫鼬就知道了那些数组,一切都应该正常工作。

请注意,在这种情况下您不需要默认值,因为Mongoose非常聪明,可以根据需要创建阵列。

2。手动将已修改的对象标记为已修改

如果出于任何原因您不希望或无法修改架构,则可以手动将analytic对象标记为已修改,以便Mongoose知道它:

user.analytic.today.push(req.body.visitor) // push the data object to the array
user.markModified('analytic'); // mark field as modified
user.save(...);

这表示Mongoose analytic或其任何子级已更改,并在调用.save时触发更新。但是请注意,Mongoose将此视为对象的完整更改,而使用选项1时,它可以使用$push