2013-05-27 13 views
8

Ho un MongoDB con una grande raccolta di "messaggi"; tutti i messaggi appartenenti a uno specifico groupId. Quindi hanno iniziato con una pubblicazione come questa:Come cancellarsi esplicitamente da una collezione?

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

e un abbonamento come questo:

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

Questo mi ha messo nei guai perché inizialmente currentGroupId è indefinito ma mongod davanzale userebbe la CPU per trovare i messaggi con groupId == null (anche se so che non ce ne sono).

Ora, ho provato a riscrivere la pubblicazione come segue:

Meteor.publish("messages", function(groupId) { 
    if (groupId) { 
    return Messages.find({ 
     groupId: groupId 
    }); 
    } else { 
    return {}; // is this the way to return an empty publication!? 
    } 
}); 

e/o di riscrivere la sottoscrizione:

Deps.autorun(function() { 
    if (Session.get("currentGroupId")) { 
    return Meteor.subscribe("messages", Session.get("currentGroupId")); 
    } else { 
    // can I put a Meteor.unsubscribe("messages") here!? 
    } 
}); 

cui entrambi aiuta inizialmente. Ma non appena lo currentGroupId diventa di nuovo indefinito (poiché l'utente naviga verso una pagina diversa), mongod è ancora occupato nella ricerca del database per l'ultimo numero registrato groupId. Quindi, come posso annullare l'iscrizione a una pubblicazione in modo tale da impedire l'interrogazione su mongod?

risposta

5

La semplice aggiunta di una condizione per la pubblicazione:

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

e mantenere l'abbonamento:

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

fa il lavoro.

Non è necessario interrompere la pubblicazione in modo esplicito. Alla fine, il MongoDB non viene più interrogato dopo aver terminato la query attualmente in esecuzione e averne emesso un altro (che sembra essere accodato da qualche parte nel sistema).

+0

Purtroppo, non ho trovato alcuna documentazione per dimostrare questa affermazione. Un suggerimento sarebbe molto apprezzato. – Dejan

7

Secondo la documentazione deve essere http://docs.meteor.com/#publish_stop

this.stop() chiamata all'interno della funzione pubblica. Arresta l'abbonamento di questo cliente; il callback onError non viene richiamato sul client.

Quindi qualcosa di simile

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

E credo che sul lato client si può semplicemente rimuovere il if/else come nel vostro primo esempio

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

Credo di avere un tipo qui. 'Messages' non ha un metodo' stop'. Suppongo che dovrebbe dire "return this.stop();" invece. – Dejan

+1

Credo che tu abbia ragione, secondo il doc la chiamata stop() è un metodo di Meteor.publish, quindi l'ho cambiato in this.stop(). – Michael

+0

Ora, la cosa divertente è che l'omissione della chiamata a stop() non modifica il comportamento. Dai un'occhiata alla mia risposta. – Dejan

0

nel tuo caso, si dovrebbe smettere il autorun

c'è un esempio nello documentation

vostro autorun è in realtà chiamato con un parametro che consente di fermarlo:

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

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

L'interruzione dell '"esecuzione automatica" non è di aiuto perché ho bisogno di caricare nuovamente i messaggi (cioè iscriversi a) una volta che "currentGroupId" non è più nullo. – Dejan

6

ho trovato più semplice e diretto per chiamare la funzione .stop() sul gestore che viene restituita dalla chiamata .subscribe():

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