2011-08-12 37 views
30

我正在使用mongoose(節點),輸出id而不是_id的最佳方式是什麼?MongoDB:輸出'id'而不是'_id'

+1

對於新的讀者:下面你會看到多個*不同的方法。在選擇之前閱讀所有內容是明智的,而不是盲目地接受或大多數選票。乾杯! – sshow

回答

18

我在我的模型上創建一個toClient()方法,我這樣做。這也是重命名/刪除你不想要發送到客戶端的其他屬性的好去處:

Schema.method('toClient', function() { 
    var obj = this.toObject(); 

    //Rename fields 
    obj.id = obj._id; 
    delete obj._id; 

    return obj; 
}); 
+0

我真的很新貓鼬,這看起來像我想要的。你怎麼稱呼這個toClient?通常我會做,找到(),然後獲取文檔對象,然後執行res.send(docs)。因此,在這種情況下,我是否要在每個文檔上調用res.write(docs [1] .toClient())?謝謝 – Johnny

+0

這似乎不適合我 - 現在在Mongoose中做到這一點的方法改變了嗎? – outside2344

+3

虛擬可能是你想要的。 – Leonidas

59

鑑於您使用的是Mongoose,您可以使用'虛擬',這實質上是Mongoose創建的虛假字段。他們不存儲在數據庫中,他們只是在運行時填充:

// Duplicate the ID field. 
Schema.virtual('id').get(function(){ 
    return this._id.toHexString(); 
}); 

// Ensure virtual fields are serialised. 
Schema.set('toJSON', { 
    virtuals: true 
}); 

任何時間的toJSON叫你從這個架構創建模型,它包括了_id相匹配的「ID」字段由Mongo生成。同樣,你可以用同樣的方法設置toObject的行爲。

參見:

可以抽象成BaseSchema這一切你的模型,然後擴展/調用保持邏輯在一個地方。我在創建Ember/Node/Mongoose應用程序時編寫了上述內容,因爲Ember真的更喜歡使用'id'字段。

+1

+1對我很好用 –

+3

非常好的解決方案(+1)。我還會添加'Schema.set('toObject',{virtuals:true})'在使用'console.log(obj)'時能夠在輸出中看到虛擬。 – Tom

+2

這使_id字段保持不變。我更喜歡變換解決方案,shakinfree提供的解決方案爲我工作。 –

19
//Transform 
Schema.options.toJSON.transform = function (doc, ret, options) { 
    // remove the _id of every document before returning the result 
    ret.id = ret._id; 
    delete ret._id; 
    delete ret.__v; 
} 

有一個「Schema.options.toObject.transform」屬性做反向或者您也可以設定爲一個虛擬的ID。

+0

感謝您的支持! –

15

以下是由@ user3087827提供的答案的替代版本。如果您發現schema.options.toJSON是不確定的,那麼你可以使用:

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

貓鼬V4.0的這個功能部分支持開箱的。不再需要手動添加@Pascal Zajac解釋的虛擬id字段。

貓鼬分配每個模式的默認 一個ID虛擬的getter返回文檔_id字段強制轉換爲字符串,或在案件的ObjectID的 ,其十六進制串。如果您不希望將模式添加到 您的模式,您可以禁用它在模式 施工時間通過此選項。Source

然而,出口這一領域的JSON,它仍然需要使系列化虛擬領域:

Schema.set('toJSON', { 
    virtuals: true 
}); 
+3

早在v4.0之前就已經是真的了,但是OP想要返回* just * id(而不是_id)。只要告訴貓鼬包括虛擬身份證件就會返回兩者。 – neverfox

3

我創建了一個易於使用的plugin爲了這個目的,我申請我的所有項目和全球所有模式。它將_id轉換爲id並剝離__v參數。

所以它轉換:

{ 
    "_id": "400e8324a71d4410b9dc3980b5f8cdea", 
    "__v": 2, 
    "name": "Item A" 
} 

要更簡單和更清潔:

{ 
    "id": "400e8324a71d4410b9dc3980b5f8cdea", 
    "name": "Item A" 
} 

用法作爲一個全球性的插件:

const mongoose = require('mongoose'); 
mongoose.plugin(require('meanie-mongoose-to-json')); 

或特定模式:

const mongoose = require('mongoose'); 
const Schema = mongoose.Schema; 
const MySchema = new Schema({}); 
MySchema.plugin(require('meanie-mongoose-to-json')); 

希望這可以幫助別人。

4

我用這個:

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

我認爲這將是巨大的,如果他們會自動抑制_id時虛函數是真實的。

0

您還可以在搜索要返回的項目時使用聚合函數。 $ project將允許您創建字段,您可以將其分配給_id。

<model>.aggregate([{$project: {_id: 0, id: '$_id'}], (err, res) => { 
// 
})