MongoDB
 sql >> Baza danych >  >> NoSQL >> MongoDB

Zrozumienie Meteor Publish / Subskrybuj

Kolekcje, publikacje i subskrypcje to trudny obszar Meteoru, który dokumentacja mogłaby omówić bardziej szczegółowo, aby uniknąć częstych nieporozumień, które czasami są wzmacniane przez mylącą terminologię.

Oto Sacha Greif (współautorka DiscoverMeteor) wyjaśniająca publikacje i subskrypcje na jednym slajdzie:

Aby właściwie zrozumieć, dlaczego musisz wywołać find() więcej niż raz, musisz zrozumieć, jak działają kolekcje, publikacje i subskrypcje w Meteor:

  1. Kolekcje definiujesz w MongoDB. Nie ma jeszcze Meteora. Te kolekcje zawierają rekordy bazy danych (nazywane również „dokumentami” zarówno przez Mongo, jak i Meteor, ale „dokument” jest bardziej ogólny niż rekord bazy danych; na przykład specyfikacja aktualizacji lub selektor zapytania również są dokumentami – obiekty JavaScript zawierające pole:wartość par).

  2. Następnie definiujesz kolekcje na serwerze Meteor z

    MyCollection = new Mongo.Collection('collection-name-in-mongo')
    

    Te kolekcje zawierają wszystkie dane z kolekcji MongoDB i możesz uruchomić MyCollection.find({...}) na nich, co zwróci kursor (zestaw rekordów wraz z metodami ich iteracji i zwracania).

  3. Ten kursor jest (przez większość czasu) używany do publikowania (wyślij) zestaw rekordów (zwany "zestawem rekordów" ). Opcjonalnie możesz opublikować tylko niektóre pola z tych rekordów. To zestawy rekordów (nie kolekcje), które klienci subskrybują do. Publikowanie odbywa się za pomocą funkcji publikowania, która jest wywoływana za każdym razem, gdy subskrybuje nowy klient i która może przyjmować parametry do zarządzania rekordami do zwrócenia (np. identyfikator użytkownika, aby zwrócić tylko dokumenty tego użytkownika).

  4. Na kliencie , masz kolekcje Minimongo, które częściowo lustro niektóre rekordów z serwera. "Częściowo", ponieważ mogą zawierać tylko niektóre pola, i "niektóre z rekordów", ponieważ zazwyczaj chcesz wysłać do klienta tylko te rekordy, których potrzebuje, aby przyspieszyć ładowanie strony i tylko te, których potrzebuje i ma pozwolenie na dostęp.

    Minimongo jest zasadniczo nietrwałą implementacją Mongo w pamięci w czystym JavaScript. Służy jako lokalna pamięć podręczna, która przechowuje tylko podzbiór bazy danych, z którą pracuje ten klient. Zapytania na kliencie (znajdź) są obsługiwane bezpośrednio z tej pamięci podręcznej, bez komunikowania się z serwerem.

    Te kolekcje Minimongo są początkowo puste. Wypełnia je

    Meteor.subscribe('record-set-name')
    

    wzywa. Zauważ, że parametr do zasubskrybowania nie jest nazwą kolekcji; to nazwa zestawu rekordów serwer używany w opublikowaniu połączenie. subscribe() wywołanie subskrybuje klienta do zestawu rekordów - podzbiór rekordów z kolekcji serwera (np. 100 ostatnich postów na blogu), ze wszystkimi lub podzbiorem pól w każdym rekordzie (np. tylko tytuł i data ). Skąd Minimongo wie, w której kolekcji umieścić przychodzące rekordy? Nazwą kolekcji będzie kolekcja argument używany w added procedury obsługi publikowania , zmieniono i usunięty wywołania zwrotne, lub jeśli ich brakuje (co ma miejsce w większości przypadków), będzie to nazwa kolekcji MongoDB na serwerze.

Modyfikowanie rekordów

W tym miejscu Meteor sprawia, że ​​wszystko jest bardzo wygodne:kiedy zmodyfikujesz rekord (dokument) w kolekcji Minimongo na kliencie, Meteor natychmiast zaktualizuje wszystkie szablony, które od niego zależą, a także odeśle zmiany z powrotem na serwer, który z kolei zapisze zmiany w MongoDB i wyśle ​​je do odpowiednich klientów, którzy zasubskrybowali zestaw rekordów zawierający ten dokument. Nazywa się to kompensacją opóźnień i jest jedną z siedmiu podstawowych zasad Meteoru.

Wiele subskrypcji

Możesz mieć kilka subskrypcji, które pobierają różne rekordy, ale wszystkie trafią do tej samej kolekcji na kliencie, jeśli pochodzą z tej samej kolekcji na serwerze, na podstawie ich _id . Nie jest to jasno wyjaśnione, ale sugerowane w dokumentacji Meteor:

Kiedy subskrybujesz zestaw rekordów, nakazuje serwerowi wysłanie rekordów do klienta. Klient przechowuje te rekordy w lokalnych kolekcjach Minimongo o tej samej nazwie co kolekcja argument używany w added procedury obsługi publikowania , zmieniono i usunięty wywołania zwrotne. Meteor będzie kolejkować przychodzące atrybuty, dopóki nie zadeklarujesz Mongo.Collection na kliencie z pasującą nazwą kolekcji.

Nie wyjaśniono, co się dzieje, gdy nie jawnie użyj dodano , zmieniono i usunięty , lub w ogóle publikuj programy obsługi — co jest w większości przypadków. W tym najczęstszym przypadku argument kolekcji jest (nie dziwi) wzięty z nazwy kolekcji MongoDB, którą zadeklarowałeś na serwerze w kroku 1. Oznacza to jednak, że możesz mieć różne publikacje i subskrypcje o różnych nazwach, a wszystkie rekordy znajdą się w tej samej kolekcji na kliencie. Aż do poziomu pól najwyższego poziomu , Meteor dba o wykonanie ustalonej unii między dokumentami, tak aby subskrypcje mogły się nakładać - publikuj funkcje, które wysyłają różne pola najwyższego poziomu do klienta, pracują obok siebie i na kliencie, dokument w kolekcji będzie unią tych dwóch zestawy pól.

Przykład:wiele subskrypcji wypełnia tę samą kolekcję na kliencie

Masz kolekcję BlogPosts, którą deklarujesz w ten sam sposób zarówno na serwerze, jak i na kliencie, mimo że robi ona różne rzeczy:

BlogPosts = new Mongo.Collection('posts');

Na kliencie BlogPosts można pobrać rekordy z:

  1. subskrypcja ostatnich 10 wpisów na blogu

    // server
    Meteor.publish('posts-recent', function publishFunction() {
      return BlogPosts.find({}, {sort: {date: -1}, limit: 10});
    }
    // client
    Meteor.subscribe('posts-recent');
    
  2. subskrypcja postów bieżącego użytkownika

    // 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);
    
  3. subskrypcja najpopularniejszych postów

  4. itd.

Wszystkie te dokumenty pochodzą z postów kolekcja w MongoDB, za pośrednictwem BlogPosts kolekcja na serwerze i trafia do BlogPosts odbiór na kliencie.

Teraz możemy zrozumieć, dlaczego musisz wywołać find() więcej niż raz - drugi raz będąc u klienta, bo dokumenty ze wszystkich abonamentów trafią do tej samej kolekcji, a Ty musisz pobierać tylko te, na których Ci zależy. Na przykład, aby uzyskać najnowsze posty na kliencie, po prostu odzwierciedlasz zapytanie z serwera:

var recentPosts = BlogPosts.find({}, {sort: {date: -1}, limit: 10});

Spowoduje to zwrócenie kursora do wszystkich dokumentów/rekordów, które klient otrzymał do tej pory, zarówno najlepszych postów, jak i postów użytkownika. (dzięki Geoffrey).



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Której bazy danych NoSQL powinienem używać do logowania?

  2. Znajdź wszystkie dokumenty w ciągu ostatnich n dni

  3. Jak połączyć zdalne mongodb z pymongo

  4. Zainstaluj MongoDB na komputerze Mac

  5. Tworzenie obszaru administracyjnego w pięć minut za pomocą AdminBro, express, mongoDB, mongoose