2011-11-13 51 views
44

Sử dụng node.js, mongodb trên mongoHQ và mongoose. Tôi đang thiết lập một lược đồ cho Danh mục. Tôi muốn sử dụng tài liệu ObjectId làm categoryId của tôi.Cách đặt ObjectId làm kiểu dữ liệu trong mongoose

var mongoose = require('mongoose'); 

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

sau đó tôi chạy

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

Chú ý rằng tôi không cung cấp giá trị cho categoryId. Tôi cho rằng đàn em mong muốn sẽ sử dụng lược đồ để tạo nó nhưng tài liệu có "_id" thông thường và không phải là "categoryId". Tôi đang làm gì sai?

Trả lời

95

Không giống như RBDM truyền thống, mongoDB không cho phép bạn xác định bất kỳ trường ngẫu nhiên nào làm khóa chính, trường _id PHẢI tồn tại cho tất cả các tài liệu chuẩn.

Vì lý do này, bạn không nên tạo trường uuid riêng biệt.

Trong mongoose, loại ObjectId được sử dụng không phải để tạo uuid mới, thay vào đó nó được sử dụng chủ yếu để tham chiếu các tài liệu khác.

Dưới đây là một ví dụ:

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

Như bạn thấy, nó sẽ không có ý nghĩa nhiều để cư categoryId với một ObjectId.

Tuy nhiên, nếu bạn muốn một trường uuid có tên độc đáo, mongoose cung cấp các thuộc tính ảo cho phép bạn ủy quyền (tham chiếu) một trường.

Check it out:

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

Vì vậy, bây giờ, bất cứ khi nào bạn gọi category.categoryId, cầy mangut chỉ trả về _id để thay thế.

Bạn cũng có thể tạo ra một phương pháp "đặt" để bạn có thể thiết lập các thuộc ảo, hãy kiểm tra this link để biết thêm

+0

Câu trả lời hoàn hảo! Cảm ơn! – idophir

+0

Sau khi thiết lập thuộc tính ảo, tôi đã thử: db.cats.find ({categoryId: ObjectId ("id")}) nhưng có kết quả null. khi tôi sử dụng db.cats.find ({_ id: ObjectId ("id")}) Tôi đã nhận được một tài liệu trở lại. Vì vậy, có vẻ như không thể sử dụng thuộc tính ảo để tìm kiếm. Tôi nghĩ rằng việc quản lý mã có thể dễ dàng hơn nếu có thể tham chiếu từng ID bằng tên rõ ràng, thay vì sử dụng _id cho mọi thứ. Chỉ là một ý nghĩ ... – idophir

12

tôi đang tìm kiếm một câu trả lời khác nhau cho các tiêu đề câu hỏi, như vậy có lẽ người khác sẽ quá.

Để thiết lập kiểu như là một ObjectId (do đó bạn có thể tham khảo author là tác giả của book, ví dụ), bạn có thể làm như sau:

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

cảm ơn vì điều này – Maverick

0

Giải pháp của tôi về việc sử dụng 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) 

Sử dụng phương thức populate của mongoose

// 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

Giải pháp do @dex cung cấp cho tôi. Nhưng tôi muốn thêm một cái gì đó khác mà cũng làm việc cho tôi: Sử dụng

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

nếu những gì bạn muốn tạo là tham chiếu Array.Nhưng nếu những gì bạn muốn là một tham chiếu đối tượng, đó là những gì tôi nghĩ rằng bạn có thể tìm kiếm dù sao, loại bỏ các dấu ngoặc từ giá trị prop, như thế này:

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

Nhìn vào 2 đoạn mã được tốt. Trong trường hợp thứ hai, giá trị prop của các sự kiện quan trọng không có dấu ngoặc trên đối tượng def.

Các vấn đề liên quan