我有一个带有大型“消息”集合的MongoDB;属于特定groupId
的所有邮件。所以从这样的出版物开始:
Meteor.publish("messages", function(groupId) {
return Messages.find({
groupId: groupId
});
});
和这样的订阅:
Deps.autorun(function() {
return Meteor.subscribe("messages", Session.get("currentGroupId"));
});
这让我陷入困境,因为最初currentGroupId
未定义,但是sill mongod将耗尽CPU来查找groupId == null
的消息(虽然我知道没有)。
现在,我尝试按如下方式重写出版物:
Meteor.publish("messages", function(groupId) {
if (groupId) {
return Messages.find({
groupId: groupId
});
} else {
return {}; // is this the way to return an empty publication!?
}
});
和/或将订阅重写为:
Deps.autorun(function() {
if (Session.get("currentGroupId")) {
return Meteor.subscribe("messages", Session.get("currentGroupId"));
} else {
// can I put a Meteor.unsubscribe("messages") here!?
}
});
最初都有帮助。但是,只要currentGroupId
再次未定义(因为用户导航到不同的页面),mongod仍然忙着为最后订阅的groupId
重新查询数据库。那么如何取消订阅出版物,以便不再查询mongod?
答案 0 :(得分:8)
根据文件,它必须是http://docs.meteor.com/#publish_stop
this.stop() 在发布函数内部调用。停止此客户的订阅; 不会在客户端上调用onError回调。
类似
Meteor.publish("messages", function(groupId) {
if (groupId) {
return Messages.find({
groupId: groupId
});
} else {
return this.stop();
}
});
我想在客户端你可以在第一个例子中删除你的if / else之类的
Deps.autorun(function() {
return Meteor.subscribe("messages", Session.get("currentGroupId"));
});
答案 1 :(得分:6)
我发现在.stop()
调用返回的处理程序上调用.subscribe()
函数更简单直接:
let handler = Meteor.subscribe('items');
...
handler.stop();
答案 2 :(得分:5)
只需在出版物中添加条件:
Meteor.publish("messages", function(groupId) {
if (groupId) {
return Messages.find({
groupId: groupId
});
});
并保留订阅:
Deps.autorun(function() {
return Meteor.subscribe("messages", Session.get("currentGroupId"));
});
完成这项工作。
无需明确停止发布。最终,在完成当前运行的查询并发出另一个查询(似乎在系统中的某个位置排队)之后,不再查询MongoDB。
答案 3 :(得分:0)
在您的情况下,您应该停止autorun
您的自动运行实际上是通过一个允许您停止它的参数调用的:
Deps.autorun(function (c) {
if (! Session.equals("shouldAlert", true))
return;
c.stop();
alert("Oh no!");
});