流星发布/订阅行为
Meteor Pub / Sub behaviour
我目前正在我的应用程序中实现实时搜索功能,但我遇到了一些让我感到困惑的行为。
背景是:我的服务器上有两个来自同一个 MongoDB 数据库的订阅,名为 posts
。
第一个订阅订阅最新的50posts,并将数据发送到MiniMongo集合Posts
.
第二个订阅订阅 post 匹配用户输入的任何搜索,并将此数据发送到 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();
});
我的问题是,我们从文档中得知:
If you pass a name when you create the collection, then you are
declaring a persistent collection — one that is stored on the server
and seen by all users. Client code and server code can both access the
same collection using the same API.
然而 PostsSearch
情况并非如此。当用户开始在客户端上搜索时,该功能会按预期完美运行——正确的光标会发送到客户端。
但是我在我的 MongoDB 数据库中没有看到 postsSearch
,同样地,PostsSearch
没有在我自己以外的任何其他客户端上填充。
这是怎么回事? self.added("postsSearch", id, fields);
似乎在做的是它能够通过网络将游标发送到客户端,但不能发送到 MongoDB 数据库。
来自文档:
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 集合,但不确定。
根据此 doc,self.added("postsSearch", id, fields);
通知 客户端文档已添加到 postsSeach
集合。
并且根据Meteor.publish:
Alternatively, a publish function can directly control its published record set by calling the functions added (to add a new document to the published record set), ...
所以我猜测 self.added
执行了这两个操作:将文档添加到 已发布的记录集 ,并通知客户端(已订阅当前出版物)。
现在如果你看到 Meteor.subscribe:
When you subscribe to a record set, it tells the server to send records to the client. The client stores these records in local Minimongo collections, with the same name as the collection argument used in the publish handler's added, changed, and removed callbacks. Meteor will queue incoming records until you declare the Mongo.Collection on the client with the matching collection name.
这表明两件事:
您有到subscribe
以便从服务器端数据库接收数据。
必须存在某种客户端代码才能创建仅限客户端的 postsSearch
集合。 (这是因为你说,服务器端数据库不存在这个集合)。
第二点很容易实现,例如:
if(Meteor.isClient) {
postsSearch = new Mongo.Collection(null);
}
在上面的示例中,postsSearch
集合将仅存在于客户端,而不存在于服务器。
关于第一个,订阅 postsSearchPub
会自动将 postsSearch
集合的数据发送到客户端(即使服务器端数据库中不存在该集合。这是因为显式调用 self.added
).
要检查的东西:根据这个doc,self.ready();
调用订阅的onReady
回调。查看此回调中的内容会很有用,也许那里定义了仅限客户端的 postsSearch
集合?
我目前正在我的应用程序中实现实时搜索功能,但我遇到了一些让我感到困惑的行为。
背景是:我的服务器上有两个来自同一个 MongoDB 数据库的订阅,名为 posts
。
第一个订阅订阅最新的50posts,并将数据发送到MiniMongo集合
Posts
.第二个订阅订阅 post 匹配用户输入的任何搜索,并将此数据发送到 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(); });
我的问题是,我们从文档中得知:
If you pass a name when you create the collection, then you are declaring a persistent collection — one that is stored on the server and seen by all users. Client code and server code can both access the same collection using the same API.
然而 PostsSearch
情况并非如此。当用户开始在客户端上搜索时,该功能会按预期完美运行——正确的光标会发送到客户端。
但是我在我的 MongoDB 数据库中没有看到 postsSearch
,同样地,PostsSearch
没有在我自己以外的任何其他客户端上填充。
这是怎么回事? self.added("postsSearch", id, fields);
似乎在做的是它能够通过网络将游标发送到客户端,但不能发送到 MongoDB 数据库。
来自文档:
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 集合,但不确定。
根据此 doc,self.added("postsSearch", id, fields);
通知 客户端文档已添加到 postsSeach
集合。
并且根据Meteor.publish:
Alternatively, a publish function can directly control its published record set by calling the functions added (to add a new document to the published record set), ...
所以我猜测 self.added
执行了这两个操作:将文档添加到 已发布的记录集 ,并通知客户端(已订阅当前出版物)。
现在如果你看到 Meteor.subscribe:
When you subscribe to a record set, it tells the server to send records to the client. The client stores these records in local Minimongo collections, with the same name as the collection argument used in the publish handler's added, changed, and removed callbacks. Meteor will queue incoming records until you declare the Mongo.Collection on the client with the matching collection name.
这表明两件事:
您有到
subscribe
以便从服务器端数据库接收数据。必须存在某种客户端代码才能创建仅限客户端的
postsSearch
集合。 (这是因为你说,服务器端数据库不存在这个集合)。
第二点很容易实现,例如:
if(Meteor.isClient) {
postsSearch = new Mongo.Collection(null);
}
在上面的示例中,postsSearch
集合将仅存在于客户端,而不存在于服务器。
关于第一个,订阅 postsSearchPub
会自动将 postsSearch
集合的数据发送到客户端(即使服务器端数据库中不存在该集合。这是因为显式调用 self.added
).
要检查的东西:根据这个doc,self.ready();
调用订阅的onReady
回调。查看此回调中的内容会很有用,也许那里定义了仅限客户端的 postsSearch
集合?