2013-05-27 82 views
8

我有一個大的「消息」集合的MongoDB;所有屬於特定groupId的消息。所以,已經開始用這樣的出版物:如何顯式取消訂閱集合?

Meteor.publish("messages", function(groupId) { 
    return Messages.find({ 
    groupId: groupId 
    }); 
}); 

和訂閱像這樣:

Deps.autorun(function() { 
    return Meteor.subscribe("messages", Session.get("currentGroupId")); 
}); 

這讓我陷入麻煩,因爲最初currentGroupId是不確定的,但門檻的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被查詢?

回答

5

簡單地增加一個條件的出版:

Meteor.publish("messages", function(groupId) { 
    if (groupId) { 
    return Messages.find({ 
     groupId: groupId 
    }); 
}); 

,並保持訂閱:

Deps.autorun(function() { 
    return Meteor.subscribe("messages", Session.get("currentGroupId")); 
}); 

完成這項工作。

沒有必要明確停止發佈。最終,在完成當前正在運行的查詢併發布另一個查詢(它似乎在系統中的某個地方排隊)後,MongoDB不再被查詢。

+0

不幸的是,我沒有找到任何文件來證明這一說法。一個提示將非常感激。 – Dejan

7

根據該文件必須是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")); 
}); 
+2

我猜你在這裏有一個類型。 'Messages'沒有'stop'方法。我想它應該說'return this.stop();'而不是。 – Dejan

+1

我相信你是對的,根據文檔調用stop()是Meteor.publish的一種方法,所以我將它改爲this.stop()。 – Michael

+0

現在,有趣的是,省略對stop()的調用不會改變行爲。看看我的答案。 – Dejan

0
你的情況

,你應該停止autorun

有一個例子documentation

你自動運行實際上是一個參數,允許叫你別再這樣:

Deps.autorun(function (c) { 
    if (! Session.equals("shouldAlert", true)) 
    return; 

    c.stop(); 
    alert("Oh no!"); 
}); 
+0

停止'autorun'將無濟於事,因爲一旦'currentGroupId'不再爲空,我需要再次加載(即訂閱)消息。 – Dejan

6

我發現它更加簡單和直接的調用,它是由該.subscribe()調用返回的句柄的.stop()功能:

let handler = Meteor.subscribe('items'); 
... 
handler.stop();