Mongoose query: remove attribute "_id", save virtual attribute "id" in the results

I am running the Express.js application 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 will look something like this:

 { "_id":"dakjdjkakda", "name":"MontyPython", "id":"dakjdjkakda" } 

due to the Virtual attribute that I defined in modelSchema.

If I changed the query select statement to:

 Model.find().select('-_id name').exec(function(err,model) {} 

Result:

 {"name":"MontyPython", "id":null } 

I believe this is because the Virtual attribute points to the _id attribute.

My question is how to remove the _id attribute in the request, but keep the id alias I created?

+6
source share
4 answers

You cannot do this. MongoDB requires the _id attribute to _id present as documentation .

Your option is to use a virtual attribute, as in your example, and possibly $ project to hide the field as a result of the request.

Otherwise, your mongo driver, such as Mongoose, should be able to hide or rename the desired field or attribute.

+2
source

If you use mongoose,

You can handle when toJSON, you can decide how it is displayed, but you cannot mention it in your request.

Model.find().select('name').exec(function(err,model) {}

  new mongoose.Schema(yourSchema, { toJSON: { transform: function(doc, ret) { ret.id = ret._id; delete ret._id; } } );} 
+5
source

You can use a global approach. Try it:

 mongoose.plugin((schema) => { schema.options.toJSON = { virtuals: true, versionKey: false, transform(doc, ret) { ret.id = ret._id; delete ret._id; } }; }); 
+2
source

Here is how I do it with a little help from lodash :)

Please note that you can hide any field by simply selecting the hide option

 customerSchema.set('toObject', { hide: '_id version passcodeHash', transform: (doc, ret, options) => _.omit(ret, options.hide.split(' ')), }) 
0
source

Source: https://habr.com/ru/post/982619/


All Articles