2015-04-02 101 views
3

我想返回,而不是“_id”的“ID”字段,使用该解决方案在猫鼬“_id”字段不能被删除

MongoDB: output 'id' instead of '_id'

下面是我的代码:

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

但是响应仍然有字段“id”和“_id”,看来delete不生效。为什么?

+1

你们是不是要建立一个没有_id场模式?那是不可能的。或者你只是试图查询一个现有的集合,而忽略返回文档中的_id字段? – Philipp 2015-04-02 09:30:26

+0

后者。我只是想在对客户端做出响应时将“_id”的名称更改为“id”。 – 2015-04-07 02:46:16

回答

5

我估计你需要的是JSON。这应该做你想要什么:

schema.options.toJSON = { 
 
    transform: function(doc, ret) { 
 
    ret.id = ret._id; 
 
    delete ret._id; 
 
    delete ret.__v; 
 
    } 
 
};

+0

另外:不要使用'ScenicSpotSchema.set('toJSON',{getters:true})',否则'schema.options.toJSON'不会生效。这意味着我不能同时使用函数'virtual'和你的解决方案。答案真的帮了我很多。谢谢! – 2015-04-07 03:33:21

1

在Mongoose上,“id”属性是默认创建的,它是一个返回“_id”值的虚拟属性。你自己不需要这样做。
如果要禁用自动创建的“ID”属性,你可以做到这一点定义模式时:

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

对于_id场,你可以告诉猫鼬不是默认你的时候创建一个使用{_id: false}属性创建一个新的Mongoose对象。但是,当您在MongoDB中使用.save()文档时,服务器将为您创建一个_id属性。
见:http://mongoosejs.com/docs/guide.html#_id

我在我的代码做的是创造一个instance method称为像returnable返回一个普通的JS对象只有我需要的属性。例如:

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 
} 
+0

这是解决我的问题,但太复杂的一种方法。无论如何,感谢您的建议,当我在数据库中的原始数据和服务器响应之间有很大的实地差异时,这将非常有用。 :) – 2015-04-07 03:10:57