文档不会使用带有 mongoose 的 save() 方法保存

Posted

技术标签:

【中文标题】文档不会使用带有 mongoose 的 save() 方法保存【英文标题】:document wont save using save() method with mongoose 【发布时间】:2019-01-06 17:37:15 【问题描述】:

我有这个架构:

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)
                
            )
        
    )
) 

我在save() 上得到doc 对象,而不是e,所以我虽然应该保存它,但它没有。

【问题讨论】:

【参考方案1】:

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

您需要创建一个新模型并保存它,而不是保存对象。

尝试创建一个新模型,如下所示将保存传递给它;

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

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

【讨论】:

成功了,谢谢。奇怪的是,我有这么多文档使用我发布的方法,而且效果很好。 Idk 为什么它现在会发生,但是.. 好吧,至少有一个解决方案【参考方案2】:

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

在您的特定场景中,您有两种选择:

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

这是最好的选择,可以更好地控制一切:

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

有了这个,这些数组现在已经被 Mongoose 知道了,一切都应该正常工作了。

请注意,在这种情况下您不需要默认值,因为 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

【讨论】:

我刚刚尝试了您的解决方案,效果很好。使用此方法是否有任何性能优势或任何其他优势? @obiwankenoobi 一般来说,我知道没有性能影响。方法 1 不太可能导致竞争条件引起的问题,而方法 2 和另一个答案可能在同一用户中可能会受到某些竞争条件的影响并行更新,但我并不完全当然。

以上是关于文档不会使用带有 mongoose 的 save() 方法保存的主要内容,如果未能解决你的问题,请参考以下文章

未来所有模型实例的 Mongoose Save 方法的Sinon Mock(带有承诺)

Mongoose 在使用 .save() 方法更新文档时抛出 E11000 重复键错误

Mongoose 模型的 save() 不会更新空数组

从 save() 返回后,mongoose 会覆盖对文档的本地更改吗?

Mongoose .save() 不保存到数据库?

通过 Model.save() 更新时触发 Mongoose 预保存挂钩