2012-09-01 150 views
21

使用流星,我不知道如何最好地處理共享同一服務器端的數據庫收集不同的客戶端集合。請看下面的例子:我有一個User收集,並在我的客戶端我有個朋友用戶的名單,我必須執行的整個用戶數據庫的查詢,返回的用戶名的列表中的搜索功能匹配查詢流星發佈/訂閱策略,獨特的客戶端集合

在發佈服務器端方法,我對同一個集合兩個查詢返回不同的文件集。這些數據是否應該在客戶端分成兩個集合?或者是否所有與兩個查詢匹配的用戶文檔都在同一個集合中?如果是後者,我會複製用於服務器端和客戶端查詢的代碼嗎?

在服務器上:

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

在客戶端:

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}}) 
    } 
}) 

這似乎是一個合理的解決方案,但不是最佳的一個。如果我想創建一個由多個服務器端集合中的搜索結果組成的新客戶端集合,該怎麼辦?

回答

24

在共享區域:

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 
} 

在服務器上:

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

在客戶端:

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(); 
    } 
}); 

從這個關鍵的外賣是在幕後發生了什麼當數據 正在通過電線傳輸並不明顯。流星似乎結合 ,在各種查詢服務器上進行匹配的記錄,並將其發送 到客戶端。然後,客戶端再次運行相同的查詢,將它們拆分爲 。

例如,假設你有20個記錄服務器端集合。然後您有 兩個發佈:第一個匹配5個記錄,第二個匹配6個,其中2個是 相同。流星將發送9條記錄。在客戶端上,然後運行確切的 您在服務器上執行的相同查詢,您應該分別以5和6 記錄結束。

+0

只是想記下我的流星如何「融合」的信息記錄可能不準確或真。如果一個流星的開發者或者更好的人可以確認,請做。我的假設是基於我個人的觀察。 – matb33

+0

看起來我的觀察結果是正確的。請參閱此答案中的「合併框」部分:http://stackoverflow.com/a/13867122/962223 – matb33

+1

當我將搜索功能放入共享文件夾時,例如lib的發佈功能可以找到它們。當我將它們放在與發佈函數相同的文件中時,它們是由發佈函數發現的,但在客戶端上不可見。想法? – cramhead

10

我有點遲到了,但有一個辦法居然有客戶端的一個服務器集合的部分在不同的集合。 在這個例子中,我有一個名爲entities的服務器集合,它包含有關polygonsrectangles的信息。
共享代碼(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'); 

客戶端代碼:

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

請記住,訂閱的姓名必須與出版物的名稱(而不是集合本身的名字)
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(); 
}); 

感謝user728291爲更簡單的解決全光照g _publishCursor()
_publishCursor()函數的第三個參數是新集合的名稱。
來源:http://docs.meteor.com/#/full/publish_added

+0

使用未記錄的[_publishCursor](https:// github),您的代碼可以縮短很多。 COM /流星/流星/ BLOB/0d33cbbfca6cc769ef6c634ca249ca40a1be6e52 /包/蒙戈/ collection.js#L301)。例如'Meteor.publish('polyEntities',function(){Mongo.Collection._publishCursor(Entities.find({shapeType:'polygon'}),this,'polyEntities'); this.ready();}); ' – user728291

+0

哇大解決方案謝謝! – PhilippSpo

+0

@ user728291你將如何處理PolyEntities集合上的更新? – PhilippSpo

0

使用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: [] 
}); 

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