如何在Mongoose中实现嵌套Schema的局部更新,避免覆盖整层嵌套属性
Mongoose 嵌套字段部分更新实现方案
经过多方案验证,可通过递归转换嵌套更新对象为Mongoose可识别的点路径格式,实现任意层级嵌套对象的部分更新,不会覆盖未传入的原有字段,实现代码如下:
const updateNestedObjectParser = (nestedUpdateObject) => { const final = {} Object.keys(nestedUpdateObject).forEach(k => { if (typeof nestedUpdateObject[k] === 'object' && !Array.isArray(nestedUpdateObject[k])) { const res = updateNestedObjectParser(nestedUpdateObject[k]) Object.keys(res).forEach(a => { final[`${k}.${a}`] = res[a] }) } else final[k] = nestedUpdateObject[k] }) return final }
使用时只需将更新对象传入该函数,将返回值作为update操作的参数即可,示例:
const parsedUpdates = updateNestedObjectParser(updates) await MainSchema.updateOne({ _id }, parsedUpdates)
问题背景
现有Mongoose结构定义如下:
ChildSchema = { childProperty: String, childProperty2: String } MainSchema = { mainProperty: String, mainProperty2: String, child: childSchema }
更新函数中希望传入MainSchema的部分对象,仅更新传入的属性。该逻辑对MainSchema的顶层属性生效,但对嵌套的childSchema无效,会直接用请求传入的部分对象覆盖整个child属性,导致原有未传入的嵌套字段被删除。
更新对象示例如下:
const updates = { child: { childProperty2: 'Example2' } }
需求为仅更新childProperty2而不删除原有的childProperty,实际业务场景中的对象体量更大,还可能存在多层嵌套,无法单独枚举每个更新字段。
曾尝试使用解构赋值实现,未生效:
const example = MainSchema.findOne({_id}) if (updates.child) example.child = {...example.child, ...updates.child} // 该方案无法生效
需要适配Mongoose 6.0版本的解决方案。
内容的提问来源于stack exchange,提问作者niksan
相关产品推荐
相关产品推荐

