2

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

背景是:我的服务器上有两个来自同一个 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();
    });
    

我的问题是,我们从文档中知道:

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

但是,情况并非如此PostsSearch。当用户开始在客户端上搜索时,该功能按预期完美运行 - 正确的光标被发送到客户端。

postsSearch但是,我在我的 MongoDB 数据库中看不到 a ,同样,PostsSearch除了我自己的客户端之外,也没有填充任何其他客户端。

这是怎么回事?看起来这样做是self.added("postsSearch", id, fields);它能够将光标向下发送到客户端,但不能发送到 MongoDB 数据库。

4

2 回答 2

1

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

根据Meteor.publish

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

所以我猜这self.added两种操作都会:将文档添加到已发布的记录集,并通知客户端(已订阅当前发布)此添加。


现在如果你看到Meteor.subscribe

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

这表明了两件事:

  1. 为了从服务器端数据库接收数据,您必须这样做。subscribe

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

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

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

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

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


要检查的东西:根据this docself.ready();调用onReady订阅的回调。看看这个回调中有什么会很有用,也许postsSearch那里定义了仅限客户端的集合?

于 2016-02-27T15:07:50.507 回答
0

从文档:

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);模拟了对集合进行了插入的事实,PostsSearch尽管显然并非如此。

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

于 2016-02-27T14:45:38.007 回答