Strategie di pubblicazione / sottoscrizione Meteor per raccolte di clienti uniche

Utilizzando Meteor, mi chiedo come sia meglio gestire diverse raccolte lato client che condividono la stessa raccolta di database lato server. Considera il seguente esempio: Ho una raccolta di User e sul mio lato client ho un elenco di utenti che sono amici e ho una funzione di ricerca che esegue una query sull’intero database degli utenti, restituendo un elenco di nomi utente che corrispondono al query .

Sul metodo Pubblica sul lato server, ho due query sulla stessa raccolta che restituiscono diversi gruppi di documenti. Dovrebbero questi dati andare in due raccolte separate sul lato client? O tutti i documenti utente che corrispondono a entrambe le query finiscono nella stessa collezione? In quest’ultimo caso, dovrei duplicare il codice utilizzato per la query lato server e lato client?

Sul server:

 Meteor.publish('searchResults', function(query){ var re = new RegExp(query, 'i') return Users.find({ 'name' : {$regex: re}}) }) 

Sul client:

 Session.set('searchQuery', null) Meteor.autosubscribe(function(){ Meteor.subscribe('searchResults', Session.get('searchQuery')) }) Template.search.events = { 'keyup #user-search' : function(e){ Session.set('searchQuery', e.target.value) } } _.extend(Template.search, { searchResults: function() { var re = new RegExp(Session.get('searchQuery'), 'i') return Users.find({ 'name' : {$regex: re}}) } }) 

Questa sembra una soluzione plausibile, ma non ottimale. Cosa succede se volevo creare una nuova raccolta lato client che consistesse di risultati di ricerca da più raccolte lato server?

In un’area condivisa:

 function getSearchUsers(query) { var re = new RegExp(query, "i"); return Users.find({name: {$regex: re}}); } function getFriendUsers() { return Users.find({friend: true}); // or however you want this to work } 

Sul server:

 Meteor.publish("searchUsers", getSearchUsers); Meteor.publish("friendUsers", getFriendUsers); 

Sul client:

 Template.search.onCreated(function () { var self = this; self.autorun(function () { self.subscribe("searchUsers", Session.get("searchQuery")); }); }); Template.friends.onCreated(function () { this.subscribe("friendUsers"); }); Template.search.helpers({ searchResults: function () { return getSearchUsers(Session.get("searchQuery")); } }); Template.friends.helpers({ results: function () { return getFriendUsers(); } }); 

La chiave da seguire è che ciò che accade dietro le quinte quando i dati vengono trasferiti sul filo non è ovvio. Meteor sembra combinare i record che sono stati abbinati nelle varie query sul server e inviarli al client. Quindi, il client esegue di nuovo la stessa query per dividerli.

Ad esempio, supponiamo di avere 20 record in una raccolta lato server. Hai quindi due pubblicazioni: la prima corrisponde a 5 record, la seconda corrisponde a 6, di cui 2 sono uguali. Meteor invierà 9 record. Sul client, si eseguono quindi le stesse query eseguite sul server e si dovrebbe finire con 5 e 6 record rispettivamente.

Sono un po ‘in ritardo per la festa, ma c’è un modo per avere effettivamente raccolte separate sul client per sottoinsiemi di una collezione di server. In questo esempio ho una collezione di server chiamata entities che contiene informazioni su polygons e rectangles .
Codice condiviso (cartella lib):

 // main collection (in this example only needed on the server Entities = new Meteor.Collection('entities'); // partial collections RectEntities = new Mongo.Collection('rectEntities'); PolyEntities = new Mongo.Collection('polyEntities'); 

Codice cliente:

 // this will fill your collections with entries from the Entities collection Meteor.subscribe('rectEntities'); Meteor.subscribe('polyEntities'); 

Ricorda che il nome dell’abbonamento deve corrispondere al nome della pubblicazione (ma non al nome della raccolta stessa)
Codice server:

 Meteor.publish('rectEntities', function(){ Mongo.Collection._publishCursor( Entities.find({shapeType: 'rectangle'}), this, 'rectEntities'); this.ready(); }); Meteor.publish('polyEntities', function(){ Mongo.Collection._publishCursor( Entities.find({shapeType: 'polygon'}), this, 'polyEntities'); this.ready(); }); 

Grazie a user728291 per la soluzione molto più semplice con _publishCursor() !
Il terzo argomento della funzione _publishCursor() è il nome della nuova raccolta.
Fonte: http://docs.meteor.com/#/full/publish_added

usa il pacchetto publish-composite

 // main collection Entities = new Meteor.Collection('entities'); // partial collections only client side RectEntities = new Mongo.Collection('rectEntities'); PolyEntities = new Mongo.Collection('polyEntities'); // server publish Meteor.publishComposite("rectEntities", function(someParameter) { return { collectionName:'rectEntities', find: function() { return Entities.find({shapeType: 'rectangle'}); }, children: [] } }); Meteor.publishComposite("polyEntities", { collectionName:'polyEntities', find: function() { return Entities.find({shapeType: 'polygon'}); }, children: [] }); 

fonte: http://braindump.io/meteor/2014/09/20/publishing-to-an-alternative-clientside-collection-in-meteor.html