I am running an Express.js app, and I have the following setup:
models.js
var schemaOptions = {
toJSON: {
virtuals: true
},
toObject: {
virtuals: true
}
};
var modelSchema = new mongoose.Schema({
name : { type: String, required: true }
}, schemaOptions);
modelSchema.virtual('id').get(function() { return this._id; });
controllers.js
exports.getModel = function(req, res) {
Model.find().select('name').exec(function(err,model) {
if (err) {
return res.status(500).json({errors:err, message: 'Internal server error'});
}
return res.status(200).json({model: model});
});
};
The result of the above query would be something like:
{ "_id":"dakjdjkakda", "name":"MontyPython", "id":"dakjdjkakda" }
because of the Virtual attribute I defined in the modelSchema.
If I change the query select statement to:
Model.find().select('-_id name').exec(function(err,model) {}
The result would be:
{"name":"MontyPython", "id":null }
I believe this happens because the Virtual attribute points to the _id attribute.
My question is, how can remove the _id attribute in the query, but keep the id alias I created?
If you are using mongoose,
You can handle in when toJSON, you can decide how it display but you can't mention it in your query.
Model.find().select('name').exec(function(err,model) {}
new mongoose.Schema(yourSchema, {
toJSON: {
transform: function(doc, ret) {
ret.id = ret._id;
delete ret._id;
}
}
);}
You might use global approach. Try this one out:
mongoose.plugin((schema) => {
schema.options.toJSON = {
virtuals: true,
versionKey: false,
transform(doc, ret) {
ret.id = ret._id;
delete ret._id;
}
};
});
You cannot do that. MongoDB requires _id
attribute to be present as per documentation.
Your option is to use virtual attribute as in your example and perhaps $project to hide the field in the query result.
Otherwise, your mongo driver, such as Mongoose, should be able to hide or rename the desired field or attribute.
You can add virtual field id
like this as you got it right in your code:
modelSchema.virtual('id').get(function () {
return this._id;
});
and then remove the actual _id
using toJSON
's transform option:
modelSchema.set('toJSON', {
virtuals: true,
transform: function(doc, ret) {
delete ret._id;
}
});
Setting virtuals: true
will make sure that your virtual field, i.e. id
will be serialized.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With