针对唯一客户端集合的Meteor发布/订阅策略

时间:2012-09-01 00:12:13

标签: javascript mongodb meteor

使用Meteor,我想知道如何最好地处理共享相同服务器端数据库集合的不同客户端集合。请考虑以下示例:我有一个User集合,在我的客户端,我有一个用户列表,我有一个搜索功能,可以对整个客户执行查询users database,返回与查询匹配的用户名列表

在发布服务器端方法上,我对同一个集合有两个查询,它们返回不同的文档集。这些数据应该在客户端分成两个独立的集合吗?或者,与两个查询匹配的所有用户文档是否最终都在同一个集合中?如果是后者,我会重复用于服务器端和客户端查询的代码吗?

在服务器上:

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

这似乎是一个看似合理的解决方案,但不是最佳解决方案。如果我想创建一个新的客户端集合,该集合由来自多个服务器端集合的搜索结果组成,该怎么办?

3 个答案:

答案 0 :(得分: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();
  }
});

这方面的关键是在数据后幕后发生的事情 是通过电线转移不明显。 Meteor似乎组合 在服务器上的各种查询中匹配的记录并发送它 到客户端。然后,客户端再次运行相同的查询进行拆分 他们分开了。

例如,假设您在服务器端集合中有20条记录。然后你有 两个发布:第一个匹配5个记录,第二个匹配6个,其中2个是 相同。 Meteor将发送9条记录。在客户端上,然后运行确切的 您在服务器上执行的相同查询,最终应该是5和6 分别记录。

答案 1 :(得分: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');

请记住,订阅的名称需要与出版物的名称相匹配(但不是集合本身的名称) 服务器代码:

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使用_publishCursor()提供更简单的解决方案! _publishCursor()函数的第三个参数是新集合的名称 资料来源:http://docs.meteor.com/#/full/publish_added

答案 2 :(得分: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