LoopBack 4 Legacy Juggler操作MongoDB时嵌入文档新增多余id字段
解决Legacy Juggler操作MongoDB时嵌套对象自动添加多余id字段的问题
最近在用LoopBack的Legacy Juggler操作MongoDB的时候,碰到个挺闹心的问题:执行findById、replaceById或者updateById这些操作时,嵌套对象里总会被自动加上多余的id字段,哪怕我根本没在嵌套模型里定义这个字段,有时候还会出现null或者undefined的情况,完全打乱了预期的数据结构。
复现步骤
先看一下当时的代码结构,很容易就能复现这个问题:
模型定义
// 嵌套模型 export class NestedDoc extends Model{ @Property() myProp1?: string; @Property() myProp2?: number; } // 主实体 export class MyEntity extends Entity { @Property({ type: 'string', id: true, }) id: string; @Property({ type: 'string', required: true, }) name: string; @Property() nested?: NestedDoc; }
控制器执行代码
await this.MyEntityRepository.replaceById( myEntity.id, myEntity );
当前问题表现
执行完替换操作后,数据库里的文档变成了这样:
{ "_id": { "$oid": "5f228e05ae69644ed8f31445" }, "name": "entityname", "nested": { "id": null, "myProp1": "prop1", "myProp2": 2 } }
同时还附带几个额外问题:
- 替换文档时控制台会弹出警告:
WARNING: id property cannot be changed from 5f228e05ae69644ed8f31445 to 5f228e05ae69644ed8f31445 for model:MyEntity in 'loaded' operation hook updateById操作也会出现同样的嵌套对象加id的问题- 用
findById查询时,返回的嵌套对象里会有一个undefined的id字段,哪怕数据库里根本没有这个字段
解决方案
这个问题的根源在于Legacy Juggler的默认行为:所有继承自Model的类,默认都会自动添加一个id属性。要解决这个问题,只需要给嵌套模型显式关闭这个默认配置就行:
1. 修改嵌套模型的配置
给NestedDoc加上@Model装饰器,并在设置里指定id: false,告诉Juggler不要给这个模型自动生成id字段:
import {Model, Property} from '@loopback/repository'; @Model({settings: {id: false}}) // 关键配置 export class NestedDoc extends Model{ @Property() myProp1?: string; @Property() myProp2?: number; }
2. 清理现有数据库中的脏数据
对于已经存在数据库里的嵌套对象id字段,可以用MongoDB的命令批量移除:
// 在MongoDB Shell中执行 db.myentities.updateMany( {"nested.id": {$exists: true}}, // 匹配所有包含nested.id的文档 {$unset: {"nested.id": ""}} // 移除该字段 );
验证效果
做完上面的配置和数据清理后,重新执行replaceById或者updateById操作,再查看数据库:
{ "_id": { "$oid": "5f228e05ae69644ed8f31445" }, "name": "entityname", "nested": { "myProp1": "prop1", "myProp2": 2 } }
嵌套对象里的多余id字段已经消失了,同时那个控制台警告也不会再出现,用findById查询返回的结果里,嵌套对象也不会有多余的id属性了。
内容的提问来源于stack exchange,提问作者Francesco Bellavita
相关产品推荐
相关产品推荐

