Mongoose Middleware - 确定是保存新文档还是更新现有文档

时间:2014-11-17 11:19:55

标签: mongoose save middleware

我有一个非常简单的问题,与在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中间件选项,但我不确定如何实现此功能,因为它看起来像{ {1}}方法要么继续保存新对象,要么抛出错误。我也不确定.pre("save", ..)是否可以在这里使用,因为它似乎是为了在保存之前验证新对象中的单个路径,而不是通常验证整个对象和确定是否保存新对象或更新现有对象,这是我需要的。

简短版:

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

.validate()

提前致谢!

1 个答案:

答案 0 :(得分: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
    });
相关问题