2011-11-13 28 views
44

在mongoHQ和mongoose上使用node.js,mongodb。我正在爲類別設置架構。我想使用文檔ObjectId作爲我的categoryId。如何將ObjectId設置爲mongoose中的數據類型

var mongoose = require('mongoose'); 

var Schema = mongoose.Schema, 
    ObjectId = Schema.ObjectId; 
var Schema_Category = new Schema({ 
    categoryId : ObjectId, 
    title  : String, 
    sortIndex : String 
}); 

我然後運行

var Category = mongoose.model('Schema_Category'); 
var category = new Category(); 
category.title = "Bicycles"; 
category.sortIndex = "3"; 

category.save(function(err) { 
    if (err) { throw err; } 
    console.log('saved'); 
    mongoose.disconnect();  
}); 

請注意,我不提供的categoryId值。我假設貓鼬會使用模式來生成它,但文檔具有通常的「_id」而不是「categoryId」。我究竟做錯了什麼?

回答

95

與傳統的RBDM不同,mongoDB不允許你定義任何隨機字段作爲主鍵,所有標準文檔必須存在_id字段。

因此,創建單獨的uuid字段沒有任何意義。

在貓鼬中,ObjectId類型用於不創建新的uuid,而是主要用於引用其他文檔。

下面是一個例子:

var mongoose = require('mongoose'); 

var Schema = mongoose.Schema, 
    ObjectId = Schema.ObjectId; 
var Schema_Product = new Schema({ 
    categoryId : ObjectId, // a product references a category _id with type ObjectId 
    title  : String, 
    price  : Number 
}); 

正如你所看到的,它不會作出太大的意義了的ObjectId填充的categoryId。

然而,如果您確實需要一個很好命名的uuid字段,mongoose會提供允許您代理(引用)字段的虛擬屬性。

檢查出來:

var mongoose = require('mongoose'); 

var Schema = mongoose.Schema, 
    ObjectId = Schema.ObjectId; 
var Schema_Category = new Schema({ 
    title  : String, 
    sortIndex : String 
}); 

Schema_Category.virtual('categoryId').get(function() { 
    return this._id; 
}); 

所以,現在,只要您撥打category.categoryId,貓鼬剛返回_id來代替。

您還可以創建一個「套」的方法,讓你可以設置虛擬財產,檢查出this link 更多信息

+0

完美答案! 謝謝! – idophir

+0

設置虛擬屬性後,我嘗試了: db.cats.find({categoryId:ObjectId(「the id」)})但得到空結果。 當我使用db.cats.find({_ id:ObjectId(「id」)})我沒有得到一個文檔。所以它看起來像虛擬財產不能用於搜索。 我認爲如果可以使用明確的名稱引用每個ID,而不是對所有內容使用_id,管理代碼可能會更容易。只是一個想法... – idophir

12

我一直在尋找一個不同的答案的問題的標題,也許其他人會太。

要設置類型作爲的ObjectId(所以你可以參考authorbook的作者,例如),你可以不喜歡:

const Book = mongoose.model('Book', { 
    author: { 
    type: mongoose.Schema.Types.ObjectId, // here you set the author ID 
              // from the Author colection, 
              // so you can reference it 
    required: true 
    }, 
    title: { 
    type: String, 
    required: true 
    } 
}); 
+0

謝謝你 – Maverick

0

我使用的ObjectId

// usermodel.js 

const mongoose = require('mongoose') 
const Schema = mongoose.Schema 
const ObjectId = Schema.Types.ObjectId 


let UserSchema = new Schema({ 
    username: { 
    type: String 
    }, 
    events: [{ 
    type: ObjectId, 
    ref: 'Event' // Reference to some EventSchema 
    }] 
}) 

UserSchema.set('autoIndex', true) 

module.exports = mongoose.model('User', UserSchema) 

解決方案使用貓鼬populate方法

// controller.js 

const mongoose = require('mongoose') 
const User = require('./usermodel.js') 

let query = User.findOne({ name: "Person" }) 

query.exec((err, user) => { 
    if (err) { 
    console.log(err) 
    } 

    user.events = events 
    // user.events is now an array of events 
}) 
0

@dex提供的解決方案爲我工作。但是我想添加一些也適用於我的東西:使用

let UserSchema = new Schema({ 
    username: { 
    type: String 
    }, 
    events: [{ 
    type: ObjectId, 
    ref: 'Event' // Reference to some EventSchema 
    }] 
}) 

如果您要創建的是數組引用。但是,如果你想要的是一個對象的引用,這是我覺得你可能會尋找無論如何,從道具卸下支架,像這樣:在2段

let UserSchema = new Schema({ 
    username: { 
    type: String 
    }, 
    events: { 
    type: ObjectId, 
    ref: 'Event' // Reference to some EventSchema 
    } 
}) 

臉色不好。在第二種情況下,鍵事件的值prop不包含對象def的括號。

相關問題