Loopback 3.x中Report模型关联Arcade模型ObjectId数组的方法
Got it, let's work through this issue—you want your report model to store an array of MongoDB ObjectIds linking to the arcade model, instead of plain strings, using LoopBack's built-in associations. I've tackled this exact scenario before, so here's a clear, step-by-step solution:
1. Update the Report Model's Field Definition (report.json)
First, you need to explicitly define the field that will hold the Arcade ObjectIds as an array of MongoDB ObjectID types. LoopBack needs this hint to avoid storing them as strings.
Inside the properties section of report.json, add or modify the field (I'll use arcadeIds as the field name—feel free to adjust it):
"arcadeIds": { "type": [ { "type": "ObjectID", "required": false } ], "id": false, "mongodb": { "dataType": "ObjectID" } }
- The
type: [{"type": "ObjectID"}]tells LoopBack this is an array of ObjectIds. - The
mongodb.dataTypeflag ensures MongoDB recognizes it as native ObjectId values instead of strings.
2. Configure the ReferencesMany Association
Next, set up the referencesMany relation in the relations section of report.json to link this field to the arcade model:
"arcades": { "type": "referencesMany", "model": "arcade", "foreignKey": "arcadeIds", "keyFrom": "_id" }
type: "referencesMany"is the right choice here because a single report can reference multiple arcades.foreignKeypoints to the field we just defined (arcadeIds) that stores the array of Arcade ObjectIds.keyFromrefers to the primary key (_id) of thearcademodel (which should already be an ObjectId by default for MongoDB models).
3. Verify the Arcade Model Setup
Double-check that your arcade.json model uses an ObjectId as its primary key (this is the default for LoopBack MongoDB models, but just to confirm):
"properties": { "_id": { "type": "ObjectID", "id": true, "generated": true }, // ... other arcade properties }
4. How to Use This Association
When creating a new Report, you can pass an array of Arcade _id strings (LoopBack will automatically convert them to MongoDB ObjectIds behind the scenes):
Report.create({ // ... other report fields arcadeIds: ["60d21b4667d0d8992e610c85", "60d21b8967d0d8992e610c86"] })
To fetch a Report along with its associated Arcades, use the include option in your query:
Report.findById(reportId, { include: 'arcades' }) .then(report => { // report.arcades will contain the full Arcade objects linked to the report });
Common Pitfalls to Avoid
- Legacy Data Migration: If you previously stored
arcadeIdsas strings, you'll need to migrate those existing values to MongoDB ObjectIds (you can do this via a MongoDB shell script or a LoopBack boot script). - Missing
mongodb.dataType: Omitting this flag is the most common reason LoopBack stores ObjectIds as strings—don't skip it! - Incorrect Relation Type: Avoid using
hasManyhere, as that would create a reverse reference in the Arcade model instead of storing the array directly in the Report model.
内容的提问来源于stack exchange,提问作者Naimish Kher

