Hai loại đối tượng dường như rất gần với nhau mà cả hai đều cảm thấy thừa. Điểm của việc có cả lược đồ và mô hình là gì?Tại sao Mongoose có cả hai lược đồ và mô hình?
Trả lời
Thường thì cách dễ nhất để trả lời loại câu hỏi này là với ví dụ. Trong trường hợp này, ai đó đã làm nó cho tôi :)
Hãy xem ở đây:
http://rawberg.com/blog/nodejs/mongoose-orm-nested-models/
EDIT: Các bài gốc (như đã đề cập trong các ý kiến) dường như không còn tồn tại , vì vậy tôi đang tái tạo nó bên dưới. Nếu nó đã trở lại, hoặc nếu nó vừa di chuyển, xin vui lòng cho tôi biết.
Nó cung cấp một mô tả phong nha của việc sử dụng lược đồ trong mô hình trong cầy mangut và tại sao bạn sẽ muốn làm điều đó, và cũng có thể cho bạn thấy làm thế nào để thúc đẩy nhiệm vụ thông qua các mô hình trong khi schema là tất cả về cấu trúc, vv
Bài đăng gốc:
Hãy bắt đầu với một ví dụ đơn giản về nhúng lược đồ vào bên trong một mô hình.
var TaskSchema = new Schema({
name: String,
priority: Number
});
TaskSchema.virtual('nameandpriority')
.get(function() {
return this.name + '(' + this.priority + ')';
});
TaskSchema.method('isHighPriority', function() {
if(this.priority === 1) {
return true;
} else {
return false;
}
});
var ListSchema = new Schema({
name: String,
tasks: [TaskSchema]
});
mongoose.model('List', ListSchema);
var List = mongoose.model('List');
var sampleList = new List({name:'Sample List'});
Tôi đã tạo đối tượng TaskSchema
mới với thông tin cơ bản mà tác vụ có thể có. Một Mongoose virtual attribute được thiết lập để thuận tiện kết hợp tên và mức độ ưu tiên của Tác vụ. Tôi chỉ xác định một getter ở đây nhưng các bộ cài đặt ảo cũng được hỗ trợ.
Tôi cũng đã xác định phương thức tác vụ đơn giản được gọi là isHighPriority
để minh họa cách các phương thức hoạt động với thiết lập này.
Trong định nghĩa ListSchema
bạn sẽ nhận thấy cách khóa nhiệm vụ được định cấu hình để giữ một mảng các đối tượng TaskSchema
. Phím nhiệm vụ sẽ trở thành một thể hiện của DocumentArray
cung cấp các phương thức đặc biệt để xử lý các tài liệu Mongo được nhúng.
Hiện tại, tôi chỉ chuyển đối tượng ListSchema
vào mongoose.model và rời khỏi TaskSchema. Về mặt kỹ thuật, không cần phải biến TaskSchema
thành một mô hình chính thức vì chúng tôi sẽ không lưu nó trong bộ sưu tập của chính nó. Sau đó tôi sẽ cho bạn thấy nó không gây hại gì nếu bạn làm và nó có thể giúp tổ chức tất cả các mô hình của bạn theo cùng một cách, đặc biệt là khi chúng bắt đầu mở rộng nhiều tệp.
Với thiết lập mô hình List
, hãy thêm một vài tác vụ vào đó và lưu chúng vào Mongo.
var List = mongoose.model('List');
var sampleList = new List({name:'Sample List'});
sampleList.tasks.push(
{name:'task one', priority:1},
{name:'task two', priority:5}
);
sampleList.save(function(err) {
if (err) {
console.log('error adding new list');
console.log(err);
} else {
console.log('new list successfully saved');
}
});
Nhiệm vụ thuộc tính về trường hợp của mô hình List
của chúng tôi (simpleList
) hoạt động giống như một mảng JavaScript thường xuyên và chúng ta có thể thêm các công việc mới để nó sử dụng push. Điều quan trọng cần lưu ý là các tác vụ được thêm vào như các đối tượng JavaScript thông thường. Đó là một sự phân biệt tinh tế có thể không trực quan ngay lập tức.
Bạn có thể xác minh từ vỏ Mongo rằng danh sách và nhiệm vụ mới đã được lưu vào mongo.
db.lists.find()
{ "tasks" : [
{
"_id" : ObjectId("4dd1cbeed77909f507000002"),
"priority" : 1,
"name" : "task one"
},
{
"_id" : ObjectId("4dd1cbeed77909f507000003"),
"priority" : 5,
"name" : "task two"
}
], "_id" : ObjectId("4dd1cbeed77909f507000001"), "name" : "Sample List" }
Bây giờ chúng tôi có thể sử dụng ObjectId
để kéo lên Sample List
và lặp lại thông qua các tác vụ của nó.
List.findById('4dd1cbeed77909f507000001', function(err, list) {
console.log(list.name + ' retrieved');
list.tasks.forEach(function(task, index, array) {
console.log(task.name);
console.log(task.nameandpriority);
console.log(task.isHighPriority());
});
});
Nếu bạn chạy bit cuối cùng của mã, bạn sẽ gặp lỗi khi nói tài liệu được nhúng không có phương thức isHighPriority
. Trong phiên bản Mongoose hiện tại, bạn không thể truy cập trực tiếp vào các phương thức trên các lược đồ được nhúng. Có open ticket để sửa lỗi và sau khi đặt câu hỏi cho Nhóm Mongoose của Google, manimal45 đã đăng một công việc hữu ích để sử dụng ngay bây giờ.
List.findById('4dd1cbeed77909f507000001', function(err, list) {
console.log(list.name + ' retrieved');
list.tasks.forEach(function(task, index, array) {
console.log(task.name);
console.log(task.nameandpriority);
console.log(task._schema.methods.isHighPriority.apply(task));
});
});
Nếu bạn chạy mã đó, bạn sẽ thấy kết quả sau trên dòng lệnh.
Sample List retrieved
task one
task one (1)
true
task two
task two (5)
false
Với ý nghĩ xung quanh, hãy biến TaskSchema
thành mẫu Mongoose.
mongoose.model('Task', TaskSchema);
var Task = mongoose.model('Task');
var ListSchema = new Schema({
name: String,
tasks: [Task.schema]
});
mongoose.model('List', ListSchema);
var List = mongoose.model('List');
Định nghĩa TaskSchema
giống như trước vì vậy tôi bỏ qua. Khi nó được chuyển thành một mô hình, chúng ta vẫn có thể truy cập đối tượng Schema cơ bản của nó bằng cách sử dụng ký hiệu chấm.
Hãy tạo danh sách mới và nhúng hai cá thể mô hình Tác vụ bên trong.
var demoList = new List({name:'Demo List'});
var taskThree = new Task({name:'task three', priority:10});
var taskFour = new Task({name:'task four', priority:11});
demoList.tasks.push(taskThree.toObject(), taskFour.toObject());
demoList.save(function(err) {
if (err) {
console.log('error adding new list');
console.log(err);
} else {
console.log('new list successfully saved');
}
});
Như chúng ta nhúng các trường hợp mô hình công tác vào Danh sách chúng tôi đang gọi điện thoại toObject
vào chúng để chuyển đổi dữ liệu của họ vào đồng bằng JavaScript đối tượng mà các List.tasks
DocumentArray
được mong đợi. Khi bạn lưu các phiên bản mẫu theo cách này, tài liệu được nhúng của bạn sẽ chứa ObjectIds
.
Ví dụ mã hoàn chỉnh là available as a gist. Hy vọng rằng những công việc xung quanh này giúp những điều tốt đẹp hơn khi Mongoose tiếp tục phát triển. Tôi vẫn còn khá mới với Mongoose và MongoDB vì vậy xin vui lòng chia sẻ các giải pháp và mẹo tốt hơn trong phần bình luận. Chúc mừng mô hình dữ liệu!
Giản đồ là một đối tượng xác định cấu trúc của bất kỳ tài liệu nào sẽ được lưu trữ trong bộ sưu tập MongoDB của bạn; nó cho phép bạn xác định các loại và trình duyệt tính hợp lệ cho tất cả các mục dữ liệu của bạn.
Mô hình là một đối tượng giúp bạn dễ dàng truy cập bộ sưu tập có tên, cho phép bạn truy vấn bộ sưu tập và sử dụng Giản đồ để xác thực bất kỳ tài liệu nào bạn lưu vào bộ sưu tập đó. Nó được tạo ra bằng cách kết hợp một Schema, một Connection và một tên bộ sưu tập.
Nguyên phrased bởi Valeri Karpov, MongoDB Blog
Tôi không nghĩ rằng câu trả lời chấp nhận thực sự trả lời cho câu hỏi đó được đặt ra. Câu trả lời không giải thích được lý do tại sao Mongoose đã quyết định yêu cầu nhà phát triển cung cấp cả biến Giản đồ và Mô hình. Một ví dụ về một khuôn khổ mà họ đã loại bỏ sự cần thiết cho nhà phát triển để xác định lược đồ dữ liệu là django - nhà phát triển viết mô hình của họ trong tệp models.py và để nó trong khuôn khổ để quản lý lược đồ. Lý do đầu tiên mà nói đến tâm trí cho lý do tại sao họ làm điều này, cho kinh nghiệm của tôi với django, là dễ sử dụng. Có lẽ quan trọng hơn là nguyên tắc DRY (không lặp lại) - bạn không cần phải nhớ cập nhật lược đồ khi bạn thay đổi mô hình - django sẽ làm điều đó cho bạn! Rails cũng quản lý lược đồ dữ liệu cho bạn - nhà phát triển không chỉnh sửa trực tiếp lược đồ, nhưng thay đổi lược đồ bằng cách xác định di chuyển điều khiển giản đồ.
Một lý do tôi có thể hiểu rằng Mongoose sẽ tách lược đồ và mô hình là các trường hợp mà bạn muốn xây dựng mô hình từ hai lược đồ. Kịch bản như vậy có thể giới thiệu phức tạp hơn là quản lý giá trị - nếu bạn có hai lược đồ được quản lý bởi một mô hình, tại sao chúng không phải là một lược đồ?
Có lẽ câu hỏi ban đầu là một di tích của hệ thống cơ sở dữ liệu quan hệ truyền thống. Trong thế giới NoSQL/Mongo trên thế giới, có lẽ lược đồ là linh hoạt hơn một chút so với MySQL/PostgreSQL, và do đó việc thay đổi lược đồ là thực hành phổ biến hơn.
Nói cách đơn giản,
Một mô hình là một mô hình đối tượng dữ liệu, như bạn sẽ tìm thấy trong một thiết kế pattern.It MVC định nghĩa Cấu trúc những loại dữ liệu phải được lưu trữ trong một cơ sở dữ liệu và những gì loại mối quan hệ dữ liệu có.
Một schema giống như một database schema
, định nghĩa về những gì sẽ được lưu trữ trong một cơ sở dữ liệu.
- 1. Tham chiếu lược đồ Mongoose
- 2. Giản đồ Mongoose trong lược đồ
- 3. Tại sao có hai lớp học, xem mô hình và mô hình miền?
- 4. Tại sao mongoose sử dụng lược đồ khi lợi ích của mongodb được cho là nó lược đồ ít hơn?
- 5. Cách thiết kế lược đồ hình sao
- 6. Thêm các biến 'ảo' vào lược đồ mongoose?
- 7. Mongoose mô hình thử nghiệm đòi hỏi mô hình
- 8. Chuyển tham số mô hình vào mô hình mongoose
- 9. Lược đồ sao có phải là lược đồ không chuẩn hóa không?
- 10. Mongoose trùng lặp với khóa lược đồ duy nhất
- 11. Tại sao tất cả các lược đồ màu MacVim của tôi trông sai?
- 12. Mongoose: Lược đồ cơ sở dữ liệu được đề xuất
- 13. Thay đổi các lược đồ trong mongoDB/mongoose
- 14. Mongoose: cách đặt trường lược đồ là ID?
- 15. Xác nhận hợp lệ nhiều thuộc tính lược đồ Mongoose?
- 16. lý do tại sao __builtins__ là cả hai mô-đun và dict
- 17. Bạn đang sử dụng lược đồ xác thực và ủy quyền nào - và tại sao?
- 18. Nút, Mongoose, các sự cố lưu nhiều chiều sâu của lược đồ lồng nhau
- 19. Mongoose - Cùng một lược đồ cho các bộ sưu tập khác nhau trong (MongoDB)
- 20. Mô hình chiến lược được mô phỏng
- 21. So sánh hai Lược đồ XML
- 22. Thực hành tốt nhất về lược đồ/truy vấn Mongoose (MongoDB, node.js)
- 23. Mongoose LoạiError trên phương pháp findOne của mô hình
- 24. Tại sao đồ thị có hình răng cưa?
- 25. Tại sao tất cả các cơ sở dữ liệu đều có lược đồ công khai trong PostgreSQL?
- 26. Xác định Mô hình Mongoose trong Mô-đun riêng biệt
- 27. Đề nghị mô hình dữ liệu Cassandra cho một lược đồ hiện có
- 28. ORM tương đương với Lược đồ Sao/Bông tuyết
- 29. JSON có lược đồ
- 30. Mẫu thích hợp cho các lược đồ lồng nhau trong Mongoose/MongoDB là gì?
Thường không nên gửi các liên kết trống như một câu trả lời cho các câu hỏi được đăng trong SO vì liên kết có thể ngừng hoạt động (như trong trường hợp này). Ít nhất là sao chép/quá khứ và trích dẫn các phần có liên quan của bài viết bạn liên kết đến. – Behrang
thực hiện - nó vẫn còn trong bộ nhớ cache của Google, vì vậy tương đối đơn giản –
Để ghi lại, vấn đề phương pháp tài liệu được nhúng đã được sửa: https://github.com/LearnBoost/mongoose/issues/249#ref-commit-e18077a – Dakota