Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

mongoose "_id" field can't be deleted

I want to return the "id" field instead of "_id",using the solution in

MongoDB: output 'id' instead of '_id'

the following is my code:

ScenicSpotSchema.virtual('id').get(function () {
    var id = this._id.toString();
    delete this._id;
    delete this.__v;
    return id;
});

But the response still have the field "id" and "_id",It seems that the delete doesn't take effect. Why?

like image 980
Ethan Wu Avatar asked Feb 10 '23 12:02

Ethan Wu


2 Answers

I'm estimating what you need is toJSON. This should do what you want:

schema.options.toJSON = {
  transform: function(doc, ret) {
    ret.id = ret._id;
    delete ret._id;
    delete ret.__v;
  }
};
like image 104
Mustafa Dokumacı Avatar answered Feb 13 '23 02:02

Mustafa Dokumacı


On Mongoose, the "id" property is created by default and it's a virtual one returning the value of "_id". You don't need to do that yourself.
If you want to disable the automatic creation of the "id" property, you can do that when defining the schema:

var schema = new Schema({ name: String }, { id: false })

For the _id field, you can tell Mongoose not to create one by default when you create a new Mongoose object, with the {_id: false} property. HOWEVER, when you .save() the document in MongoDB, the server WILL create an _id property for you.
See: http://mongoosejs.com/docs/guide.html#_id

What I do in my code is creating an instance method called something like returnable that returns a plain JS object with just the properties I need. For example:

userSchema.methods.returnable = function(context) {
    // Convert this to a plain JS object
    var that = this.toObject()

    // Add back virtual properties
    that.displayName = this.displayName

    // Manually expose selected properties
    var out = {}
    out['id'] = that._id

    var expose = ['name', 'displayName', 'email', 'active', 'verified', 'company', 'position', 'address', 'phone']
    for(var i in expose) {
        var key = expose[i]
        out[key] = that[key]

        // Change objects to JS objects
        if(out[key] && typeof out[key] === 'object' && !Array.isArray(out[key])) {
            // Change empty objects (not array) to undefined
            if(!Object.keys(out[key]).length) {
                out[key] = undefined
            }
        }
    }

    return out
}
like image 32
ItalyPaleAle Avatar answered Feb 13 '23 03:02

ItalyPaleAle