22

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

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

4

3 回答 3

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 条记录。

于 2012-10-25T20:29:37.677 回答
10

我参加聚会有点晚了,但是有一种方法可以在客户端上为一个服务器集合的子集提供单独的集合。在此示例中,我有一个名为的服务器集合entities,其中包含有关polygonsand的信息rectangles
共享代码(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

于 2014-12-18T10:12:50.933 回答
0

使用发布复合

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

于 2015-07-01T09:47:31.840 回答