对findByIdAndUpdate进行一致的预保存validation

我试图find一个一致的方式来validation我保存到一个数组中的一些ID。

架构:

var MySchema = new Schema({ name: { type: String }, otherIds: [{type: Schema.Types.ObjectId, ref: 'Other'}] }); 

几个更新语句:

根据ID更新整个文档

 var update = { otherIds: someIds }; MyModel.findByIdAndUpdate(id, event, ...); 

让我们只需添加到其他ID集:

 var update = { $addToSet: { otherIds: someId } }; MyModel.findByIdAndUpdate(id, update, ...); 

所以据我所知,有几种方法来validation这些ID,但是我遇到了所有这些问题。

  1. 使用保存中间件。 这不起作用,因为使用findAndUpdate命令时不会调用中间件。

  2. 使用findOneAndUpdate中间件。 这可能是最有希望的,因为这两个中间件都将被调用。 但是尝试从update语句中提取otherIds是不一致的,因为每个更新语句都有很大不同。 这似乎很脆弱,因为任何时候有人添加一个新的更新声明,他们可能不得不修改这个中间件,以适应一个可能不同的更新声明。

  3. 使用validation器。 我已经尝试过使用validation器,它对第一次更新非常有效,但不会为第二次更新运行。 根据文档,validation器只运行$ set和$ unset命令,$ addToSet不属于该类别。

还有其他的select,或者我可能错过了什么?

另一个解决scheme是首先调用findById(...) ,然后调用.save()该文档。

如果你需要坚持findByIdAndUpdate(...) ,你也可以使用查询中间件 (需要mongoose> = 4)

 schema.pre('update', function() { this.update({},{ $set: { updatedAt: new Date() } }); }); 

但是,该解决scheme的问题是, this是查询对象,而不是文档,这不是validation的理想select。