2013-07-17 31 views
6

Na moim projekcie meteorowym użytkownicy mogą publikować wydarzenia i muszą wybrać (przez autouzupełnianie), w którym mieście się to odbędzie. Mam pełną listę francuskich miast i nigdy nie będę aktualizowany.Czy istnieje sposób, aby powiedzieć meteorowi, że kolekcja jest statyczna (nigdy się nie zmieni)?

Chcę użyć kolekcji i subskrybcji publikowania na podstawie danych wejściowych autouzupełniania, ponieważ nie chcę, aby klient pobierał pełną bazę danych (5 MB). Czy istnieje sposób, aby pokazać meteorowi, że ta kolekcja jest "statyczna"? Czy to nie robi różnicy?

Czy ktoś mógłby zaproponować inne podejście?

Odpowiedz

7

Kiedy „chcesz poinformować serwer, że kolekcja jest statyczna”, zdaję sobie sprawę z dwóch potencjalnych optymalizacje:

  1. Nie obserwować bazy danych za pomocą rekordów na żywo, ponieważ dane nie zmienią
  2. nie przechowywać wyniki tej kwerendy w merge box ponieważ nie muszą być śledzone i porównane z innymi danymi (oszczędność pamięci i CPU)

(1) jest czymś, co można zrobić dość łatwo przez skonstruowanie własnego kursora publikowania. Jednakże, jeśli klient obserwuje to samo zapytanie, wierzę, że Meteor (przynajmniej w przyszłości) zoptymalizuje go, dlatego wciąż jest to jedno aktywne zapytanie dla dowolnej liczby klientów. Jeśli chodzi o (2), nie jestem świadomy żadnego prostego sposobu, aby to zrobić, ponieważ może to zepsuć łączenie danych ponad multiple publications and subscriptions.

Aby uniknąć użycia zapytania na żywo, można ręcznie dodać dane do funkcji publikowania zamiast zwracać kursor, co powoduje wywołanie funkcji .observe() w celu podłączenia danych do subskrypcji. Oto prosty przykład:

Meteor.publish(function() { 
    var sub = this; 
    var args = {}; // what you're find()ing 

    Foo.find(args).forEach(function(document) { 
     sub.added("client_collection_name", document._id, document); 
    }); 

    sub.ready(); 
}); 

To spowoduje, że dane mają być dodane do client_collection_name po stronie klienta, które mogłyby mieć taką samą nazwę jak kolekcji odwołuje Foo, czy coś innego. Należy pamiętać, że można zrobić many other things with publications

aktualizację (również patrz powyższy link.): Aby rozwiązać problemy z (2), które mogą być potencjalnie bardzo problematyczne w zależności od wielkości zbiorów, konieczne jest obejście Meteor w ogóle. Zobacz https://stackoverflow.com/a/21835534/586086, aby uzyskać jeden sposób. Innym sposobem jest po prostu zwrócić kolekcję fetch() ed jako wywołanie metody, choć nie ma to zalet kompresji.

+1

ta powinna być przyjęta odpowiedź aż 2 może zostać rozwiązany. Dzięki Andrew –

+1

@WesJohnson zobacz http://stackoverflow.com/a/21835534/586086, jak rozwiązać # 2. Również zaktualizuję tę odpowiedź w pewnym momencie. –

3

Od Meteor doc: "Każda zmiana w kolekcji, która zmienia dokumenty w kursorze, spowoduje ponowne obliczenie. Aby wyłączyć to zachowanie, przekaż {reaktywne: false} jako opcję do znalezienia."

myślę, że to prosta opcja jest najlepszą odpowiedzią

+0

'reaktywny: false' działa tylko po stronie klienta. –

0

Nie trzeba opublikować całą kolekcję. 1. Pokaż opcje autouzupełniania dopiero po wprowadzeniu przez użytkownika pierwszych 3 liter - znacznie zawęzi to wyszukiwanie.
2.Zapewnij nie więcej niż 5-10 miast jako opcje - dzięki temu Twój zestaw rekordów będzie naprawdę mały - nie będzie więc konieczne przesyłanie 5 milionów danych każdemu użytkownikowi.
Twoja publikacja powinna wyglądać następująco:

Meteor.publish('pub-name', function(userInput){ 
    var firstLetters = new RegExp('^' + userInput); 
    return Cities.find({name:firstLetters},{limit:10,sort:{name:1}}); 
}); 
Powiązane problemy