MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

Wie funktioniert das Beispiel zum Zählen von Nachrichten in Meteor-Dokumenten?

Danke, dass Sie mich dazu veranlasst haben, eine klarere Erklärung zu schreiben. Hier ist ein vollständigeres Beispiel mit meinen Kommentaren. Es gab ein paar Fehler und Inkonsistenzen, die ich bereinigt habe. Die nächste Version der Dokumentation wird dies verwenden.

Meteor.publish ist recht flexibel. Es ist nicht darauf beschränkt, bestehende MongoDB-Sammlungen für den Kunden zu veröffentlichen:Wir können alles veröffentlichen, was wir wollen. Genauer gesagt Meteor.publish definiert einen Satz von Dokumenten die ein Client abonnieren kann. Jedes Dokument gehört zu einem Sammlungsnamen (einer Zeichenfolge) und hat eine eindeutige _id Feld und hat dann einen Satz von JSON-Attributen. Wenn sich die Dokumente im Satz ändern, sendet der Server die Änderungen an jeden abonnierten Client und hält den Client auf dem neuesten Stand.

Wir werden hier einen Dokumentensatz namens "counts-by-room" definieren , das ein einzelnes Dokument in einer Sammlung mit dem Namen "counts" enthält . Das Dokument hat zwei Felder:eine roomId mit der ID eines Raums und count :die Gesamtzahl der Nachrichten in diesem Raum. Es gibt keine echte MongoDB-Sammlung namens counts . Dies ist nur der Name der Sammlung, die unser Meteor-Server an den Client heruntersendet und auf einer Client-Seite speichert Sammlung namens counts .

Dazu nimmt unsere Veröffentlichungsfunktion eine roomId entgegen Parameter, der vom Client kommt, und beobachtet eine Abfrage aller Nachrichten (an anderer Stelle definiert) in diesem Raum. Wir können die effizienteren observeChanges verwenden Form der Beobachtung einer Abfrage hier, da wir nicht das vollständige Dokument benötigen, sondern nur das Wissen, dass ein neues hinzugefügt oder entfernt wurde. Immer wenn eine neue Nachricht mit der roomId hinzugefügt wird an denen wir interessiert sind, erhöht unser Callback die interne Zählung und veröffentlicht dann ein neues Dokument für den Client mit dieser aktualisierten Gesamtzahl. Und wenn eine Nachricht entfernt wird, wird der Zähler verringert und das Update an den Client gesendet.

Beim ersten Aufruf von observeChanges , einige added Rückrufe werden sofort für jede bereits vorhandene Nachricht ausgeführt. Dann werden zukünftige Änderungen immer dann ausgelöst, wenn Nachrichten hinzugefügt oder entfernt werden.

Unsere Veröffentlichungsfunktion registriert auch einen onStop Handler zum Aufräumen, wenn der Client sich abmeldet (entweder manuell oder beim Trennen). Dieser Handler entfernt die Attribute vom Client und beendet die laufenden observeChanges .

Eine Veröffentlichungsfunktion wird jedes Mal ausgeführt, wenn ein neuer Client "counts-by-room" abonniert , sodass jeder Client eine observeChanges hat läuft in seinem Namen.

// server: publish the current size of a collection
Meteor.publish("counts-by-room", function (roomId) {
  var self = this;
  var count = 0;
  var initializing = true;

  var handle = Messages.find({room_id: roomId}).observeChanges({
    added: function (doc, idx) {
      count++;
      if (!initializing)
        self.changed("counts", roomId, {count: count});  // "counts" is the published collection name
    },
    removed: function (doc, idx) {
      count--;
      self.changed("counts", roomId, {count: count});  // same published collection, "counts"
    }
    // don't care about moved or changed
  });

  initializing = false;

  // publish the initial count. `observeChanges` guaranteed not to return
  // until the initial set of `added` callbacks have run, so the `count`
  // variable is up to date.
  self.added("counts", roomId, {count: count});

  // and signal that the initial document set is now available on the client
  self.ready();

  // turn off observe when client unsubscribes
  self.onStop(function () {
    handle.stop();
  });
});

Jetzt können wir dies auf dem Client wie ein typisches Meteor-Abonnement behandeln. Zuerst brauchen wir eine Mongo.Collection das unser berechnetes Zählungsdokument enthalten wird. Da der Server in eine Sammlung namens "counts" veröffentlicht übergeben wir "counts" als Argument für die Mongo.Collection Konstruktor.

// client: declare collection to hold count object
Counts = new Mongo.Collection("counts");

Dann können wir abonnieren. (Sie können tatsächlich abonnieren, bevor Sie die Sammlung deklarieren:Meteor wird die eingehenden Updates in eine Warteschlange stellen, bis es einen Platz gibt, um sie abzulegen.) Der Name des Abonnements ist "counts-by-room" , und es braucht ein Argument:die ID des aktuellen Raums. Ich habe dies in Deps.autorun gepackt also als Session.get('roomId') ändert, wird der Kunde automatisch die alte Raumzählung abbestellen und die neue Raumzählung neu abonnieren.

// client: autosubscribe to the count for the current room
Tracker.autorun(function () {
  Meteor.subscribe("counts-by-room", Session.get("roomId"));
});

Endlich haben wir das Dokument in Counts und wir können es wie jede andere Mongo-Sammlung auf dem Client verwenden. Jede Vorlage, die auf diese Daten verweist, wird automatisch neu gezeichnet, wenn der Server eine neue Zählung sendet.

// client: use the new collection
console.log("Current room has " + Counts.findOne().count + " messages.");