【问题标题】:Mongoose Middleware - Determine whether to save new or update existing documentMongoose 中间件 - 确定是保存新文档还是更新现有文档
【发布时间】:2015-01-14 07:09:03
【问题描述】:

我有一个与在 Mongoose 中保存对象有关的非常简单的问题。我搜索了类似的问题,但没有遇到任何符合我特定问题的人。

我将在下面提供详细解释,并以简短的摘要结束。

问题:

假设我有一个看起来像这样的集合。

var ObjectId = Mongoose.Types.ObjectId;

var UserAnswer = new Schema({
  userId: {type: ObjectId, ref: "UserModel"},
  surveyId: {type: ObjectId, ref: "SurveyModel"},
  score: Number,
  timestamp: {type: Date, default: Date.now()}
});

这里需要注意的是,UserAnswer 架构没有任何唯一索引,这意味着用户可以多次回答同一个调查。

但是,如果用户尝试再次回答调查(在经过一定时间之前),我希望更新最新的现有 UserAnswer 文档。

我当然可以在保存新对象之前手动检查它,但我的问题是是否有更聪明的方法来做到这一点,例如通过中间件?

我查看了 Mongoose API 文档中的 prevalidate 中间件选项,但我不确定我将如何实现它,因为看起来 .pre("save", ..) 方法要么继续保存新对象或抛出错误。我也不确定是否可以在这里使用.validate(),因为它似乎旨在在保存之前验证新对象中的单个路径,而不是通常验证整个对象并确定是否保存新对象对象或更新现有的,这是我需要的。

短版:

我能否通过 Mongoose 中间件确定是保存新的 Mongoose 对象还是更新现有的对象。示例:如果下面的查询返回数据,则更新现有文档,否则保存新文档。

UserAnswer
  .find({ userId: userId, surveyId: surveyId, timestamp: { $gte: startOfToday } })
  .sort({ timestamp: -1 })
  .limit(1)
  .exec(function(err, res) { ... })

提前致谢!

【问题讨论】:

    标签: mongoose save middleware


    【解决方案1】:

    我相信使用findOneAndUpdate 方法和upsert 选项可以实现您想要的结果。如果一条记录不存在,这将插入一条新记录,如果找到匹配项,则更新现有记录。

    UserAnswer.findOneAndUpdate({ userId: userId, surveyId: surveyId, timestamp: { $gte: startOfToday } }, 
        {userId: userId, surveyId: surveyId, score: score, timestamp: Date.now()},
        {upsert: true, sort: {timestamp: -1}}, 
        function(err, doc) {
            //do something with the results
        });
    

    【讨论】:

      猜你喜欢
      • 2019-10-05
      • 1970-01-01
      • 2015-02-09
      • 2013-06-10
      • 2018-12-20
      • 2020-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多