sql >> Database >  >> NoSQL >> MongoDB

Hoe werkt het voorbeeld van het aantal berichten in Meteor-documenten?

Bedankt dat je me hebt gevraagd een duidelijkere uitleg te schrijven. Hier is een vollediger voorbeeld met mijn opmerkingen. Er waren een paar bugs en inconsistenties die ik heb opgeruimd. De volgende release van documenten zal dit gebruiken.

Meteor.publish is vrij flexibel. Het is niet beperkt tot het publiceren van bestaande MongoDB-collecties voor de klant:we kunnen alles publiceren wat we willen. In het bijzonder Meteor.publish definieert een set documenten waarop een cliënt zich kan abonneren. Elk document hoort bij een collectienaam (een tekenreeks), heeft een unieke _id veld, en heeft dan een aantal JSON-kenmerken. Als de documenten in de set veranderen, stuurt de server de wijzigingen naar elke geabonneerde client, zodat de client up-to-date blijft.

We gaan hier een documentenset definiëren, genaamd "counts-by-room" , dat een enkel document bevat in een verzameling met de naam "counts" . Het document heeft twee velden:een roomId met de ID van een kamer, en count :het totale aantal berichten in die kamer. Er is geen echte MongoDB-verzameling met de naam counts . Dit is gewoon de naam van de verzameling die onze Meteor-server naar de client zal sturen en zal opslaan in een client-side verzameling met de naam counts .

Om dit te doen, heeft onze publicatiefunctie een roomId . nodig parameter die van de client komt, en een query van alle berichten (elders gedefinieerd) in die kamer observeert. We kunnen de efficiëntere observeChanges . gebruiken vorm van het observeren van een vraag hier, omdat we niet het volledige document nodig hebben, alleen de wetenschap dat er een nieuwe is toegevoegd of verwijderd. Telkens wanneer een nieuw bericht wordt toegevoegd met de roomId waarin we geïnteresseerd zijn, onze callback verhoogt de interne telling en publiceert vervolgens een nieuw document aan de klant met dat bijgewerkte totaal. En wanneer een bericht wordt verwijderd, verlaagt het de telling en stuurt het de client de update.

Wanneer we observeChanges voor het eerst aanroepen , een aantal added callbacks worden meteen uitgevoerd, voor elk bericht dat al bestaat. Toekomstige wijzigingen worden dan geactiveerd wanneer berichten worden toegevoegd of verwijderd.

Onze publicatiefunctie registreert ook een onStop handler om op te ruimen wanneer de klant zich uitschrijft (handmatig of bij het verbreken). Deze handler verwijdert de attributen van de client en breekt de lopende observeChanges af .

Elke keer dat een nieuwe klant zich abonneert op "counts-by-room" . wordt er een publicatiefunctie uitgevoerd , dus elke klant heeft een observeChanges namens hem lopen.

// 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();
  });
});

Nu, op de client, kunnen we dit net als een typisch Meteor-abonnement behandelen. Ten eerste hebben we een Mongo.Collection . nodig dat ons document met berekende tellingen bevat. Aangezien de server publiceert in een verzameling met de naam "counts" , we geven "counts" door als het argument voor de Mongo.Collection constructeur.

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

Dan kunnen we ons inschrijven. (U kunt zich daadwerkelijk abonneren voordat u de collectie declareert:Meteor zal de binnenkomende updates in de wachtrij plaatsen totdat er een plaats is om ze te plaatsen.) De naam van het abonnement is "counts-by-room" , en er is één argument voor nodig:de ID van de huidige kamer. Ik heb dit verpakt in Deps.autorun zodat als Session.get('roomId') wijzigingen, zal de klant zich automatisch afmelden voor de telling van de oude kamer en zich opnieuw abonneren op de telling van de nieuwe kamer.

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

Eindelijk hebben we het document in Counts en we kunnen het net als elke andere Mongo-collectie op de client gebruiken. Elke sjabloon die naar deze gegevens verwijst, wordt automatisch opnieuw getekend wanneer de server een nieuwe telling verzendt.

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


  1. 'process.nextTick(function() { throw err; })' - Undefined is geen functie (mongodb/mongoose)

  2. Waarom moet ik Redis-verbindingen sluiten of open houden?

  3. NoSQL-gegevensstreaming met MongoDB en Kafka

  4. Een SQL LIKE-instructie gebruiken in MongoDB