Mongoose查询:删除“_id”属性,在结果中保留虚拟属性“id”

时间:2015-02-17 17:00:32

标签: node.js mongodb

我正在运行Express.js应用程序,我有以下设置:

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});
    });
};

上述查询的结果如下:

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

因为我在modelSchema中定义了虚拟属性。

如果我将查询select语句更改为:

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

结果将是:

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

我相信这是因为Virtual属性指向_id属性。

我的问题是,如何删除查询中的_id属性,但保留我创建的id别名?

5 个答案:

答案 0 :(得分:5)

如果您使用的是猫鼬,

您可以处理何时toJSON,您可以决定它的显示方式,但您无法在查询中提及它。

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

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

答案 1 :(得分:2)

你做不到。 MongoDB根据documentation要求_id属性。

您的选择是在示例中使用虚拟属性,也可以使用$project隐藏查询结果中的字段。

否则,您的mongo驱动程序(例如Mongoose)应该能够隐藏或重命名所需的字段或属性。

答案 2 :(得分:2)

您可以使用全球方法。试试这个:

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

答案 3 :(得分:1)

您可以在代码中正确添加虚拟字段id

modelSchema.virtual('id').get(function () {

    return this._id;
});

,然后使用_id的transform选项删除实际的toJSON

modelSchema.set('toJSON', {
    virtuals: true,
    transform: function(doc, ret) {
        delete ret._id;
    }
});

设置virtuals: true将确保您的虚拟字段,即id将被序列化。

答案 4 :(得分:0)

这是我在lodash的帮助下完成的方法:)

请注意,您只需设置hide选项即可隐藏所需的任何字段

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