Koleksi, publikasi, dan langganan adalah area Meteor yang rumit, yang dapat didiskusikan oleh dokumentasi secara lebih rinci, untuk menghindari kebingungan yang sering terjadi, yang terkadang diperkuat oleh terminologi yang membingungkan.
Inilah Sacha Greif (penulis DiscoverMeteor) yang menjelaskan publikasi dan langganan dalam satu slide:
Untuk memahami dengan benar mengapa Anda perlu memanggil find()
lebih dari sekali, Anda perlu memahami cara kerja koleksi, publikasi, dan langganan di Meteor:
-
Anda mendefinisikan koleksi di MongoDB. Belum ada Meteor yang terlibat. Koleksi ini berisi data basis data (juga disebut "dokumen" oleh Mongo dan Meteor, tetapi "dokumen" lebih umum daripada catatan database; misalnya, spesifikasi pembaruan atau pemilih kueri juga merupakan dokumen - objek JavaScript yang berisi
field: value
berpasangan). -
Kemudian Anda mendefinisikan koleksi di server Meteor dengan
MyCollection = new Mongo.Collection('collection-name-in-mongo')
Koleksi ini berisi semua data dari koleksi MongoDB, dan Anda dapat menjalankan
MyCollection.find({...})
pada mereka, yang akan mengembalikan kursor (satu set record, dengan metode untuk mengulanginya dan mengembalikannya). -
Kursor ini (sebagian besar waktu) digunakan untuk menerbitkan (kirim) satu set catatan (disebut "kumpulan catatan" ). Anda dapat memublikasikan hanya beberapa bidang dari catatan tersebut. Ini adalah kumpulan rekor (bukan koleksi) yang berlangganan clients oleh klien ke. Penerbitan dilakukan oleh fungsi publikasikan, yang dipanggil setiap kali klien baru berlangganan, dan yang dapat mengambil parameter untuk mengelola catatan mana yang akan dikembalikan (misalnya id pengguna, untuk mengembalikan hanya dokumen pengguna tersebut).
-
Di klien , Anda memiliki koleksi Minimongo yang sebagian cerminkan beberapa dari catatan dari server. "Sebagian" karena mungkin hanya berisi beberapa bidang, dan "beberapa catatan" karena Anda biasanya ingin mengirim ke klien hanya catatan yang dibutuhkan, untuk mempercepat pemuatan halaman, dan hanya yang dibutuhkan dan memiliki izin untuk mengakses.
Minimongo pada dasarnya adalah implementasi Mongo dalam memori dan non-persisten dalam JavaScript murni. Ini berfungsi sebagai cache lokal yang menyimpan hanya subset dari database yang bekerja dengan klien ini. Kueri pada klien (temukan) disajikan langsung dari cache ini, tanpa berbicara dengan server.
Koleksi Minimongo ini awalnya kosong. Mereka diisi oleh
Meteor.subscribe('record-set-name')
panggilan. Perhatikan bahwa parameter untuk berlangganan bukanlah nama koleksi; itu adalah nama dari kumpulan rekaman bahwa server yang digunakan dalam
publish
panggilan.subscribe()
panggilan membuat klien berlangganan kumpulan rekaman - subset record dari kumpulan server (mis. 100 entri blog terbaru), dengan semua atau subset bidang di setiap record (mis. hanyatitle
dandate
). Bagaimana Minimongo tahu ke dalam koleksi mana untuk menempatkan catatan yang masuk? Nama koleksinya adalahcollection
argumen yang digunakan dalamadded
penangan publikasi ,changed
, danremoved
callback, atau jika tidak ada (yang sering terjadi), itu akan menjadi nama koleksi MongoDB di server.
Memodifikasi catatan
Di sinilah Meteor membuat segalanya menjadi sangat nyaman:ketika Anda memodifikasi catatan (dokumen) dalam koleksi Minimongo di klien, Meteor akan segera memperbarui semua templat yang bergantung padanya, dan juga akan mengirim perubahan kembali ke server, yang pada gilirannya akan menyimpan perubahan di MongoDB dan akan mengirimkannya ke klien yang sesuai yang telah berlangganan kumpulan catatan termasuk dokumen itu. Ini disebut kompensasi latensi dan merupakan salah satu dari tujuh prinsip inti Meteor.
Beberapa langganan
Anda dapat memiliki banyak langganan yang menarik catatan yang berbeda, tetapi semuanya akan berakhir di koleksi yang sama di klien jika berasal dari koleksi yang sama di server, berdasarkan _id
mereka . Ini tidak dijelaskan dengan jelas, tetapi tersirat oleh dokumen Meteor:
Saat Anda berlangganan kumpulan catatan, itu memberi tahu server untuk mengirim catatan ke klien. Klien menyimpan catatan ini di koleksi Minimongo lokal, dengan nama yang sama dengan
collection
argumen yang digunakan dalamadded
penangan publikasi ,changed
, danremoved
panggilan balik. Meteor akan mengantri atribut masuk sampai Anda mendeklarasikan Mongo.Collection pada klien dengan nama koleksi yang cocok.
Apa yang tidak dijelaskan adalah apa yang terjadi jika Anda tidak secara eksplisit menggunakan added
, changed
dan removed
, atau publikasikan penangan sama sekali - yang paling sering terjadi. Dalam kasus yang paling umum ini, argumen koleksi (tidak mengejutkan) diambil dari nama koleksi MongoDB yang Anda nyatakan di server pada langkah 1. Tetapi ini berarti Anda dapat memiliki publikasi dan langganan yang berbeda dengan nama yang berbeda, dan semua catatan akan berakhir di koleksi yang sama pada klien. Turun ke tingkat bidang tingkat atas , Meteor berhati-hati untuk melakukan penyatuan yang ditetapkan di antara dokumen, sehingga langganan dapat tumpang tindih - fungsi publikasikan yang mengirimkan bidang tingkat atas yang berbeda ke klien bekerja berdampingan dan pada klien, dokumen dalam koleksi akan menjadi gabungan keduanya kumpulan bidang.
Contoh:beberapa langganan mengisi koleksi yang sama di klien
Anda memiliki koleksi BlogPosts, yang Anda deklarasikan dengan cara yang sama di server dan klien, meskipun melakukan hal yang berbeda:
BlogPosts = new Mongo.Collection('posts');
Di klien, BlogPosts
bisa mendapatkan catatan dari:
-
berlangganan 10 posting blog terbaru
// server Meteor.publish('posts-recent', function publishFunction() { return BlogPosts.find({}, {sort: {date: -1}, limit: 10}); } // client Meteor.subscribe('posts-recent');
-
berlangganan posting pengguna saat ini
// server Meteor.publish('posts-current-user', function publishFunction() { return BlogPosts.find({author: this.userId}, {sort: {date: -1}, limit: 10}); // this.userId is provided by Meteor - http://docs.meteor.com/#publish_userId } Meteor.publish('posts-by-user', function publishFunction(who) { return BlogPosts.find({authorId: who._id}, {sort: {date: -1}, limit: 10}); } // client Meteor.subscribe('posts-current-user'); Meteor.subscribe('posts-by-user', someUser);
-
berlangganan ke pos paling populer
- dst.
Semua dokumen ini berasal dari posts
koleksi di MongoDB, melalui BlogPosts
koleksi di server, dan berakhir di BlogPosts
koleksi pada klien.
Sekarang kami dapat memahami mengapa Anda perlu memanggil find()
lebih dari sekali - kedua kalinya berada di klien, karena dokumen dari semua langganan akan berakhir di koleksi yang sama, dan Anda hanya perlu mengambil dokumen yang Anda sayangi. Misalnya, untuk mendapatkan posting terbaru di klien, Anda cukup mencerminkan kueri dari server:
var recentPosts = BlogPosts.find({}, {sort: {date: -1}, limit: 10});
Ini akan mengembalikan kursor ke semua dokumen/catatan yang telah diterima klien sejauh ini, baik posting teratas maupun posting pengguna. (terima kasih Geoffrey).