sql >> Base de Datos >  >> NoSQL >> MongoDB

Comprender Meteor Publicar / Suscribirse

Las colecciones, publicaciones y suscripciones son un área complicada de Meteor, que la documentación podría discutir con más detalle, para evitar confusiones frecuentes, que a veces se amplifican con terminología confusa.

Aquí está Sacha Greif (coautora de DiscoverMeteor) explicando publicaciones y suscripciones en una diapositiva:

Para comprender correctamente por qué necesita llamar a find() más de una vez, debe comprender cómo funcionan las colecciones, publicaciones y suscripciones en Meteor:

  1. Usted define colecciones en MongoDB. Ningún meteorito involucrado todavía. Estas colecciones contienen registros de base de datos (también llamados "documentos" tanto por Mongo como por Meteor, pero un "documento" es más general que un registro de base de datos; por ejemplo, una especificación de actualización o un selector de consulta también son documentos:objetos de JavaScript que contienen field: value parejas).

  2. Luego define las colecciones en el servidor Meteor con

    MyCollection = new Mongo.Collection('collection-name-in-mongo')
    

    Estas colecciones contienen todas los datos de las colecciones MongoDB, y puede ejecutar MyCollection.find({...}) sobre ellos, que devolverá un cursor (un conjunto de registros, con métodos para recorrerlos y devolverlos).

  3. Este cursor se usa (la mayoría de las veces) para publicar (enviar) un conjunto de registros (llamado "conjunto de registros" ). Opcionalmente, puede publicar solo algunos campos de esos registros. Son conjuntos de registros (no colecciones) que los clientes suscriben para. La publicación se realiza mediante una función de publicación, que se llama cada vez que un nuevo cliente se suscribe y que puede tomar parámetros para administrar qué registros devolver (por ejemplo, una identificación de usuario, para devolver solo los documentos de ese usuario).

  4. En el cliente , tienes colecciones de Minimongo que parcialmente espejo algo de los registros del servidor. "Parcialmente" porque pueden contener solo algunos de los campos, y "algunos de los registros" porque generalmente desea enviar al cliente solo los registros que necesita, para acelerar la carga de la página, y solo aquellos que necesita y tiene permiso para acceder.

    Minimongo es esencialmente una implementación no persistente en memoria de Mongo en JavaScript puro. Sirve como un caché local que almacena solo el subconjunto de la base de datos con la que está trabajando este cliente. Las consultas en el cliente (buscar) se atienden directamente desde este caché, sin hablar con el servidor.

    Estas colecciones de Minimongo están inicialmente vacías. Son llenados por

    Meteor.subscribe('record-set-name')
    

    llamadas Tenga en cuenta que el parámetro para suscribirse no es un nombre de colección; es el nombre de un conjunto de registros que el servidor usó en la publish llamar. El subscribe() la llamada suscribe al cliente a un conjunto de registros - un subconjunto de registros de la colección del servidor (p. ej., las 100 publicaciones de blog más recientes), con todos o un subconjunto de los campos en cada registro (p. ej., solo title) y date ). ¿Cómo sabe Minimongo en qué colección colocar los registros entrantes? El nombre de la colección será collection argumento utilizado en el controlador de publicación added , changed y removed devoluciones de llamada, o si faltan (que es el caso la mayor parte del tiempo), será el nombre de la colección MongoDB en el servidor.

Modificar registros

Aquí es donde Meteor hace las cosas muy convenientes:cuando modifica un registro (documento) en la colección de Minimongo en el cliente, Meteor actualizará instantáneamente todas las plantillas que dependen de él y también enviará los cambios al servidor, que a su vez almacenará los cambios en MongoDB y los enviará a los clientes apropiados que se hayan suscrito a un conjunto de registros que incluya ese documento. Esto se llama compensación de latencia y es uno de los siete principios básicos de Meteor.

Suscripciones múltiples

Puede tener un montón de suscripciones que obtengan diferentes registros, pero todas terminarán en la misma colección en el cliente si provienen de la misma colección en el servidor, según su _id . Esto no se explica claramente, pero está implícito en los documentos de Meteor:

Cuando se suscribe a un conjunto de registros, le dice al servidor que envíe registros al cliente. El cliente almacena estos registros en colecciones locales de Minimongo, con el mismo nombre que la collection argumento utilizado en el controlador de publicación added , changed y removed devoluciones de llamada Meteor pondrá en cola los atributos entrantes hasta que declare Mongo.Collection en el cliente con el nombre de colección coincidente.

Lo que no se explica es lo que sucede cuando no usar explícitamente added , changed y removed , o publicar controladores en absoluto, que es la mayor parte del tiempo. En este caso más común, el argumento de la colección se toma (como era de esperar) del nombre de la colección MongoDB que declaró en el servidor en el paso 1. Pero lo que esto significa es que puede tener diferentes publicaciones y suscripciones con diferentes nombres, y todos los los registros terminarán en la misma colección en el cliente. Hasta el nivel de campos de nivel superior , Meteor se ocupa de realizar una unión establecida entre los documentos, de modo que las suscripciones puedan superponerse:las funciones de publicación que envían diferentes campos de nivel superior al trabajo del cliente en paralelo y en el cliente, el documento de la colección será la unión de los dos conjuntos de campos.

Ejemplo:múltiples suscripciones llenando la misma colección en el cliente

Tiene una colección BlogPosts, que declara de la misma manera tanto en el servidor como en el cliente, aunque hace cosas diferentes:

BlogPosts = new Mongo.Collection('posts');

En el cliente, BlogPosts puede obtener registros de:

  1. una suscripción a las 10 publicaciones de blog más recientes

    // server
    Meteor.publish('posts-recent', function publishFunction() {
      return BlogPosts.find({}, {sort: {date: -1}, limit: 10});
    }
    // client
    Meteor.subscribe('posts-recent');
    
  2. una suscripción a las publicaciones del usuario actual

    // server
    Meteor.publish('posts-current-user', function publishFunction() {
      return BlogPosts.find({author: this.userId}, {sort: {date: -1}, limit: 10});
      // this.userId is provided by Meteor - http://docs.meteor.com/#publish_userId
    }
    Meteor.publish('posts-by-user', function publishFunction(who) {
      return BlogPosts.find({authorId: who._id}, {sort: {date: -1}, limit: 10});
    }
    
    // client
    Meteor.subscribe('posts-current-user');
    Meteor.subscribe('posts-by-user', someUser);
    
  3. una suscripción a las publicaciones más populares

  4. etc.

Todos estos documentos provienen de las posts colección en MongoDB, a través de BlogPosts colección en el servidor y terminan en BlogPosts colección en el cliente.

Ahora podemos entender por qué necesita llamar a find() más de una vez, la segunda vez en el cliente, porque los documentos de todas las suscripciones terminarán en la misma colección y solo necesita buscar aquellos que le interesan. Por ejemplo, para obtener las publicaciones más recientes en el cliente, simplemente refleja la consulta del servidor:

var recentPosts = BlogPosts.find({}, {sort: {date: -1}, limit: 10});

Esto devolverá un cursor a todos los documentos/registros que el cliente ha recibido hasta el momento, tanto las publicaciones principales como las publicaciones del usuario. (gracias Geoffrey).