Node.js客户端属性缺失:Mongoose对象新增字段无法返回
Hey, I've run into this exact issue before! Let me break down what's happening and how to fix it without modifying your Mongoose Schema.
The item you're working with isn't a plain JavaScript object—it's a Mongoose Document instance. These objects are tightly bound to your Mongo Schema, so only fields defined in the Schema get serialized when you send them via res.json(). Your mention field isn't in the Schema, so Mongoose automatically filters it out when converting the Document to JSON.
Here are a few straightforward solutions, ordered by how clean and efficient they are:
1. Convert the Document to a Plain JS Object
The easiest quick fix is to use Mongoose's toObject() method to turn the Document into a regular JS object. Once you do that, you can add any fields you want without Mongoose interfering:
// Convert Mongoose Document to plain object const plainItem = item.toObject(); // Add your mention field plainItem.mention = [{ id: 1, /* other properties */ }]; // Send the response res.json({ status: 1, message: 'success', data: plainItem });
You can also use toJSON() here, but toObject() makes it clearer that you're working with a vanilla object now.
2. Use lean() in Your Query (Recommended)
If you don't need any of Mongoose's Document features (like .save(), validation, or middleware) for this specific query, use the lean() method when fetching the item. This tells Mongoose to return a plain JS object right away, so you can modify it freely:
// Fetch as plain object directly from the query const item = await ItemModel.findOne({ id: 1 }).lean(); // Add mention without any restrictions item.mention = [{ id: 1, /* other properties */ }]; res.json({ status: 1, message: 'success', data: item });
This is my go-to solution because it's more efficient—Mongoose doesn't have to create a full Document instance, which saves a bit of processing power.
3. Force the Field onto the Document (Less Ideal)
If you absolutely need to keep the Document instance, you can use the set() method with the strict: false option to bypass Schema checks:
// Force add the mention field item.set('mention', [{ id: 1, /* other properties */ }], { strict: false }); // Now it will be included in the JSON response res.json({ status: 1, message: 'success', data: item });
I don't recommend this as much because it can lead to unexpected behavior if you're not careful. Stick with the first two methods if possible.
内容的提问来源于stack exchange,提问作者user9575054

