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

Meteor publish/subscribe strategies for unique client-side collections

本文关键字:策略 唯一 客户端 集合 Meteor      更新时间:2023-09-26

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

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

在服务器上:

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

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

在共享区域中:

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条为同样。Meteor将发送9条记录。然后在客户端上运行与您在服务器上执行的查询相同,结果应该是5和6分别记录。

我来晚了一点,但有一种方法可以在客户端上为一个服务器集合的子集设置单独的集合。在这个例子中,我有一个名为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();
});

感谢用户728291使用_publishCursor()提供了更简单的解决方案
_publishCursor()函数的第三个参数是新集合的名称
来源:http://docs.meteor.com/#/full/publish_added

使用发布复合包

// 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