Các bộ sưu tập, ấn phẩm và đăng ký là một lĩnh vực khó khăn của Meteor mà tài liệu có thể thảo luận chi tiết hơn, để tránh nhầm lẫn thường xuyên , đôi khi bị khuếch đại bởi thuật ngữ khó hiểu .
Đây là Sacha Greif (đồng tác giả của DiscoverMeteor ) giải thích các ấn phẩm và đăng ký trong một trang trình bày:
Để hiểu đúng lý do tại sao bạn cần gọi find()
nhiều lần, bạn cần hiểu cách hoạt động của các bộ sưu tập, ấn phẩm và đăng ký trong Meteor:
Bạn xác định bộ sưu tập trong MongoDB. Chưa có Meteor nào tham gia. Những bộ sưu tập chứa các hồ sơ cơ sở dữ liệu (hay còn gọi là "tài liệu" bởi cả hai Mongo và Meteor , nhưng một "tài liệu" là tổng quát hơn mức kỷ lục cơ sở dữ liệu, ví dụ, một đặc điểm kỹ thuật cập nhật hoặc chọn truy vấn là các tài liệu quá - JavaScript đối tượng chứa field: value
cặp).
Sau đó, bạn xác định các bộ sưu tập trên máy chủ Meteor với
MyCollection = new Mongo.Collection('collection-name-in-mongo')
Các bộ sưu tập này chứa tất cả dữ liệu từ các bộ sưu tập MongoDB và bạn có thể chạy MyCollection.find({...})
trên chúng, nó sẽ trả về một con trỏ (một tập hợp các bản ghi, với các phương thức để lặp qua chúng và trả về chúng).
Con trỏ này (hầu hết thời gian) được sử dụng để xuất bản (gửi) một tập hợp các bản ghi (được gọi là "tập bản ghi" ). Bạn có thể tùy ý xuất bản chỉ một số trường từ các bản ghi đó. Nó là các bộ hồ sơ ( không phải bộ sưu tập) mà khách hàng đăng ký . Việc xuất bản được thực hiện bởi một hàm xuất bản , được gọi mỗi khi một khách hàng mới đăng ký và có thể nhận các tham số để quản lý bản ghi nào sẽ trả về (ví dụ: id người dùng, để chỉ trả lại tài liệu của người dùng đó).
Trên máy khách , bạn có bộ sưu tập Minimongo phản chiếu một phần một số bản ghi từ máy chủ. "Một phần" vì chúng có thể chỉ chứa một số trường và "một số bản ghi" bởi vì bạn thường chỉ muốn gửi cho máy khách những bản ghi mà nó cần, để tăng tốc độ tải trang và chỉ những bản nó cần và có quyền truy cập.
Minimongo về cơ bản là một triển khai trong bộ nhớ, không liên tục của Mongo trong JavaScript thuần túy. Nó phục vụ như một bộ nhớ cache cục bộ chỉ lưu trữ tập hợp con của cơ sở dữ liệu mà ứng dụng khách này đang làm việc. Các truy vấn trên máy khách (tìm) được phục vụ trực tiếp từ bộ nhớ cache này mà không cần trao đổi với máy chủ.
Các bộ sưu tập Minimongo này ban đầu trống. Chúng được lấp đầy bởi
Meteor.subscribe('record-set-name')
cuộc gọi. Lưu ý rằng tham số để đăng ký không phải là tên bộ sưu tập; đó là tên của một tập hợp bản ghi mà máy chủ đã sử dụng trong publish
cuộc gọi. Lệnh subscribe()
gọi đăng ký máy khách vào một tập hợp bản ghi - một tập hợp con các bản ghi từ bộ sưu tập máy chủ (ví dụ: 100 bài đăng blog gần đây nhất), với tất cả hoặc một tập hợp con của các trường trong mỗi bản ghi (ví dụ: chỉ title
và date
). Làm thế nào Minimongo biết được vào bộ sưu tập nào để đặt các bản ghi đến? Tên của bộ sưu tập sẽ là collection
lập luận được sử dụng trong các công bố của bộ xử lý added
, changed
và removed
callbacks, hoặc nếu những người đang mất tích (đó là trường hợp hầu hết thời gian), nó sẽ là tên của bộ sưu tập MongoDB trên máy chủ.
Sửa đổi hồ sơ
Đây là lúc Meteor làm cho mọi thứ trở nên rất thuận tiện: khi bạn sửa đổi bản ghi (tài liệu) trong bộ sưu tập Minimongo trên máy khách, Meteor sẽ cập nhật ngay lập tức tất cả các mẫu phụ thuộc vào nó và cũng sẽ gửi các thay đổi trở lại máy chủ, lần lượt sẽ lưu trữ các thay đổi trong MongoDB và sẽ gửi chúng đến các ứng dụng khách thích hợp đã đăng ký một bộ hồ sơ bao gồm tài liệu đó. Đây được gọi là bù độ trễ và là một trong bảy nguyên tắc cốt lõi của Meteor .
Nhiều đăng ký
Bạn có thể có một loạt các đăng ký kéo các bản ghi khác nhau, nhưng tất cả chúng sẽ kết thúc trong cùng một bộ sưu tập trên máy khách nếu chúng đến từ cùng một bộ sưu tập trên máy chủ, dựa trên chúng _id
. Điều này không được giải thích rõ ràng, nhưng được ngụ ý bởi các tài liệu về Meteor:
Khi bạn đăng ký một tập hợp bản ghi, nó sẽ yêu cầu máy chủ gửi các bản ghi đến máy khách. Các cửa hàng khách hàng những hồ sơ trong các bộ sưu tập Minimongo địa phương, với tên giống như collection
lập luận được sử dụng trong các công bố của bộ xử lý added
, changed
và removed
callbacks. Meteor sẽ xếp hàng các thuộc tính đến cho đến khi bạn khai báo Mongo.Collection trên máy khách với tên bộ sưu tập phù hợp.
Có gì không được giải thích là những gì xảy ra khi bạn không sử dụng một cách rõ ràng added
, changed
và removed
, hoặc xuất bản xử lý ở tất cả - đó là hầu hết thời gian. Trong trường hợp phổ biến nhất này, đối số tập hợp (không có gì đáng ngạc nhiên) được lấy từ tên của tập hợp MongoDB mà bạn đã khai báo trên máy chủ ở bước 1. Nhưng điều này có nghĩa là bạn có thể có các ấn phẩm và đăng ký khác nhau với các tên khác nhau và tất cả các bản ghi sẽ kết thúc trong cùng một bộ sưu tập trên máy khách. Xuống đến cấp của các trường cấp cao nhất , Meteor đảm nhận việc thực hiện liên kết tập hợp giữa các tài liệu, sao cho các đăng ký có thể chồng chéo lên nhau - xuất bản các chức năng vận chuyển các trường cấp cao nhất khác nhau cho máy khách làm việc song song với máy khách, tài liệu trong bộ sưu tập sẽ làsự kết hợp của hai nhóm trường .
Ví dụ: nhiều đăng ký lấp đầy cùng một bộ sưu tập trên máy khách
Bạn có một bộ sưu tập BlogPosts, mà bạn khai báo theo cùng một cách trên cả máy chủ và máy khách, mặc dù nó thực hiện những việc khác nhau:
BlogPosts = new Mongo.Collection('posts');
Trên máy khách, BlogPosts
có thể lấy hồ sơ từ:
đăng ký 10 bài đăng trên blog gần đây nhất
Meteor.publish('posts-recent', function publishFunction() {
return BlogPosts.find({}, {sort: {date: -1}, limit: 10});
}
Meteor.subscribe('posts-recent');
đăng ký các bài đăng của người dùng hiện tại
Meteor.publish('posts-current-user', function publishFunction() {
return BlogPosts.find({author: this.userId}, {sort: {date: -1}, limit: 10});
}
Meteor.publish('posts-by-user', function publishFunction(who) {
return BlogPosts.find({authorId: who._id}, {sort: {date: -1}, limit: 10});
}
Meteor.subscribe('posts-current-user');
Meteor.subscribe('posts-by-user', someUser);
đăng ký các bài đăng phổ biến nhất
- Vân vân.
Tất cả các tài liệu này đến từ posts
bộ sưu tập trong MongoDB, thông qua BlogPosts
bộ sưu tập trên máy chủ và kết thúc trong BlogPosts
bộ sưu tập trên máy khách.
Bây giờ chúng tôi có thể hiểu tại sao bạn cần gọi find()
nhiều lần - lần thứ hai trên máy khách, vì tài liệu từ tất cả các đăng ký sẽ kết thúc trong cùng một bộ sưu tập và bạn chỉ cần tìm nạp những tài liệu bạn quan tâm. Ví dụ: để nhận các bài đăng gần đây nhất trên máy khách, bạn chỉ cần phản chiếu truy vấn từ máy chủ:
var recentPosts = BlogPosts.find({}, {sort: {date: -1}, limit: 10});
Thao tác này sẽ trả về một con trỏ đến tất cả các tài liệu / bản ghi mà khách hàng đã nhận được cho đến nay, cả bài đăng hàng đầu và bài đăng của người dùng. ( cảm ơn Geoffrey ).
BlogPosts.find({})
trên máy khách sau khi đăng ký cả hai ấn phẩm — tức là nó sẽ trả về con trỏ của tất cả các tài liệu / bản ghi hiện có trên máy khách, cả bài đăng hàng đầu và bài đăng của người dùng. Tôi đã thấy các câu hỏi khác trên SO mà người hỏi đã bối rối vì điều này.