Meteor Pub / Sub行为

时间:2016-02-27 13:27:28

标签: mongodb meteor minimongo

我目前正在我的应用中实现实时搜索功能,而且我遇到了一些我很困惑的行为。

背景是:我在服务器上的同一个MongoDB数据库中有两个订阅,名为posts

  1. 第一个订阅订阅最新的50个帖子,并将数据发送到MiniMongo集合Posts

  2. 第二个订阅订阅匹配用户输入的任何搜索的帖子,并将此数据发送到MiniMongo集合PostsSearch,如下所示。

    // client
    
    Posts = new Mongo.Collection('posts');
    
    PostsSearch = new Mongo.Collection('postsSearch');
    
    // server
    
    Meteor.publish('postsPub', function(options, search) {
    
        return Posts.find(search, options);
    
    });
    
    Meteor.publish('postsSearchPub', function(options, search) {
    
        var self = this;
    
        var subHandle = Posts.find(search, options).observeChanges({
    
            added: function (id, fields) {
    
                self.added("postsSearch", id, fields);
    
            }
    
        });
    
        self.ready();
    });
    
  3. 我的问题是,我们从文档中了解到:

      

    如果您在创建集合时传递名称,那么您就是   声明持久集合 - 存储在服务器上的集合   并被所有用户看到。客户端代码和服务器代码都可以访问   使用相同API的相同集合。

    然而PostsSearch并非如此。当用户开始在客户端上搜索时,该功能可以完美地按预期工作 - 将正确的游标发送到客户端。

    但是我的MongoDB数据库中没有postsSearch,同样地,PostsSearch没有在我自己以外的任何其他客户端上填充。

    这是怎么回事?什么是self.added("postsSearch", id, fields);似乎可以做到这一点,它能够将游标发送到客户端,而不是发送到MongoDB数据库。

2 个答案:

答案 0 :(得分:1)

根据此docself.added("postsSearch", id, fields); 通知客户端已将文档添加到postsSeach集合中。

根据Meteor.publish

  

或者,发布功能可以通过调用添加功能(将新文档添加到已发布的记录集)直接控制其已发布的记录集,...

所以我猜测self.added执行这两项操作:将文档添加到发布的记录集,并通知客户端(已订阅当前的出版物) )这个补充。

现在,如果您看到Meteor.subscribe

  

订阅记录集时,它会告诉服务器将记录发送到客户端。客户端将这些记录存储在本地Minimongo集合中,其名称与发布处理程序的添加,更改和删除的回调中使用的集合参数相同。 Meteor将对传入的记录进行排队,直到您在客户端上使用匹配的集合名称声明Mongo.Collection。

这表明有两件事:

  1. subscribe以便从服务器端数据库接收数据。

  2. 必须存在某种客户端代码才能创建仅限客户端的postsSearch集合。 (这是因为你说过,这个集合并不存在于服务器端数据库中)。

  3. 第二点可以很容易地实现,例如:

    if(Meteor.isClient) {
      postsSearch = new Mongo.Collection(null);
    }
    

    在上面的示例中,postsSearch集合仅存在于客户端而不存在于服务器上。

    关于第1个,订阅postsSearchPub将自动将postsSearch集合的数据发送给客户端(即使服务器端数据库中不存在所述集合。是因为显式调用self.added)。

    要检查的内容:根据此docself.ready();会调用订阅的onReady回调。查看此回调中的内容会很有用,也许在那里定义了仅限客户端的postsSearch集合?

答案 1 :(得分:0)

来自doc:

SafeArrayCreate(VT_I4, 1, &bounds);

这意味着行this.added(collection, id, fields) Call inside the publish function. Informs the subscriber that a document has been added to the record set. 会模仿已经对self.added("postsSearch", id, fields);集合进行了插入这一事实,尽管事实并非如此。

关于没有MongoDB集合,它可能与Meteor懒惰有关,它在第一次插入时会创建MongoDB集合,但不确定。