MongoDB findOneAndUpdate返回不匹配过滤条件文档问题排查
问题原因
这是Mongoose默认严格模式(strict mode)的标准行为,和MongoDB本身无关。
Mongoose会基于你定义的Model Schema做字段过滤:如果userModel对应的Schema中没有声明accountId字段,Mongoose在组装查询条件时,会自动剔除所有Schema中不存在的字段,不会把这些字段发给MongoDB。这就是你debug日志里最终执行的查询只剩id: '7'条件的根本原因。
由于实际发往MongoDB的查询只有id匹配条件,你库里那条id为'7'的文档自然会被命中并更新,和它有没有accountId属性无关。
排查确认
直接检查userModel对应的Schema定义即可验证,你当前的Schema大概率没有声明accountId字段,类似下面的结构:
const userSchema = new mongoose.Schema({ id: String, name: String, properties: Object // 缺失accountId字段声明 }) module.exports = mongoose.model('users', userSchema)
修复方法
二选一即可:
- 推荐方案:在Schema中补全
accountId字段定义
这是最符合Mongoose设计规范的做法,补全后Mongoose就会正常把该字段加入查询条件:const userSchema = new mongoose.Schema({ id: String, accountId: mongoose.Schema.Types.ObjectId, // 类型和你acc._id的实际类型保持一致即可 name: String, properties: Object }) - 临时方案:本次查询关闭严格模式校验
如果你确实不需要在Schema中维护accountId字段,可以在findOneAndUpdate的配置项中加入strict: false,告诉Mongoose不要过滤本次查询中Schema未声明的字段:const existingUser = await this.userModel.findOneAndUpdate( {id: id, accountId: acc._id}, {$set: {name, properties}}, { new: true, strict: false } )
注意:你debug日志中
properties被序列化为Map类型,也是Schema字段类型不匹配导致的,建议同步核对该字段的Schema声明是否和实际业务结构一致,避免出现非预期的类型转换。
内容的提问来源于stack exchange,提问作者Luis Novo
相关产品推荐
相关产品推荐

