MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Meteor :différence entre les noms des collections, des variables, des publications et des abonnements ?

Distinguons les différents noms que vous pourriez avoir à gérer lors de la programmation de Meteor :

  • Noms des variables , comme Posts = new Meteor.Collection(...) . Ceux-ci sont utilisés uniquement pour que votre code sache comment accéder à cette variable. Meteor ne sait pas ou ne se soucie pas de ce que c'est, bien que la convention soit de capitaliser.
  • Noms des collections , comme new Meteor.Collection("posts") . Cela correspond au nom d'une collection MongoDB (sur le serveur) ou d'une collection minimongo (sur le client).
  • Noms des publications et des abonnements , utilisé dans Meteor.publish("foo", ...) ou Meteor.subscribe("foo") . Celles-ci doivent correspondre pour que le client s'abonne à certaines données sur le serveur.

Il y a deux choses que vous devez faire correspondre dans le modèle de données Meteor :

  1. Noms des publications et leurs abonnements correspondants
  2. (habituellement) Noms des collections sur le client et le serveur, si vous utilisez le modèle de collection par défaut

Un nom d'abonnement doit toujours correspondre au nom d'une publication. Cependant, les collections envoyées pour un abonnement donné n'ont rien à voir avec le nom de l'abonnement. En fait, on peut envoyer plusieurs curseurs dans une seule publication ou une collection sur différentes publications ou même plusieurs abonnements par publication , qui apparaissent fusionnés en un seul dans le client. Vous pouvez également avoir des noms de collection différents dans le serveur et le client; lisez la suite...

Passons en revue les différents cas :

  1. Modèle d'abonnement simple . C'est celui que vous voyez habituellement dans les démos simples de Meteor.

    Sur le client et le serveur,

    Posts = new Meteor.Collection("posts");
    

    Sur serveur uniquement :

    Meteor.publish("postsPub", function() { 
        return Posts.find() 
    });
    

    Sur le client uniquement :

    Meteor.subscribe("postsPub")
    

    Cela synchronise les Posts collection (nommée posts dans la base de données) en utilisant la publication appelée postsPub .

  2. Plusieurs collections dans une seule publication . Vous pouvez envoyer plusieurs curseurs pour une seule publication, en utilisant un tableau.

    Sur client et serveur :

    Posts = new Meteor.Collection("posts");
    Comments = new Meteor.Collection("comments");
    

    Sur serveur uniquement :

    Meteor.publish("postsAndComments", function() { 
        return [ 
            Posts.find(), 
            Comments.find() 
        ]; 
    });
    

    Sur le client uniquement :

    Meteor.subscribe("postsAndComments");
    

    Cela synchronise les Posts collection ainsi que les Comments collection à l'aide d'une seule publication appelée postsAndComments . Ce type de publication est bien adapté aux données relationnelles; par exemple, si vous souhaitez publier uniquement certaines publications et les commentaires associés uniquement à ces publications. Voir un package qui peut créer ces curseurs automatiquement .

  3. Plusieurs publications pour une seule collection . Vous pouvez utiliser plusieurs publications pour envoyer différentes tranches de données pour une seule collection qui sont automatiquement fusionnées par Meteor.

    Sur serveur et client :

    Posts = new Meteor.Collection("posts");
    

    Sur serveur uniquement :

    Meteor.publish("top10Posts", function() { 
        return Posts.find({}, {
            sort: {comments: -1}, 
            limit: 10
        });
    });        
    Meteor.publish("newest10Posts", function() { 
        return Posts.find({}, {
            sort: {timestamp: -1},
            limit: 10
        }); 
    });
    

    Sur le client uniquement :

    Meteor.subscribe("top10Posts");
    Meteor.subscribe("newest10Posts");
    

    Cela pousse à la fois les 10 messages avec le plus de commentaires ainsi que les 10 messages les plus récents sur le site vers l'utilisateur, qui voit les deux ensembles de données fusionnés en un seul Posts le recueil. Si l'un des messages les plus récents est également un message avec le plus de commentaires ou vice versa, les Posts collection contiendra moins de 20 articles. Ceci est un exemple de la façon dont le modèle de données de Meteor vous permet d'effectuer de puissantes opérations de fusion de données sans implémenter vous-même les détails.

  4. Plusieurs abonnements par publication. Vous pouvez obtenir plusieurs ensembles de données à partir de la même publication en utilisant différents arguments.

    Sur serveur et client :

    Posts = new Meteor.Collection("posts");
    

    Sur serveur uniquement :

    Meteor.publish("postsByUser", function(user) { 
        return Posts.find({
            userId: user
        });
    });        
    

    Sur le client uniquement :

    Meteor.subscribe("postsByUser", "fooUser");
    Meteor.subscribe("postsByUser", "barUser");
    

    Cela provoque les messages de fooUser et barUser pour qu'ils apparaissent tous les deux dans les posts le recueil. Ce modèle est pratique lorsque vous avez plusieurs calculs différents qui examinent différentes tranches de vos données et peuvent être mis à jour dynamiquement. Notez que lorsque vous vous abonnez dans un Deps.autorun(...) , Meteor appelle stop() sur n'importe quel handle d'abonnement précédent avec le même nom automatiquement, mais si vous utilisez ces abonnements en dehors d'un autorun vous devrez les arrêter vous-même. À l'heure actuelle, vous ne pouvez pas faire deux abonnements avec le même nom dans un autorun calcul, car Meteor ne peut pas les différencier.

  5. Pousser des données arbitraires sur une publication. Vous pouvez entièrement personnaliser les publications pour ne pas exiger les mêmes noms de collection sur le serveur et le client. En fait, le serveur peut publier des données qui ne sont pas du tout sauvegardées par une collection. Pour ce faire, vous pouvez utiliser l'API pour les fonctions de publication .

    Sur serveur uniquement :

    Posts = new Meteor.Collection("posts"); 
    
    Meteor.publish("newPostsPub", function() {
        var sub = this;
        var subHandle = null;
    
        subHandle = Posts.find({}, {
            sort: {timestamp: -1},
            limit: 10
        })
        .observeChanges({
            added: function(id, fields) {
                sub.added("newposts", id, fields);            
            },
            changed: function(id, fields) {
                sub.changed("newposts", id, fields);            
            },
            removed: function(id) {
                sub.removed("newposts", id);
            }
        });
    
        sub.ready();
    
        sub.onStop(function() {
            subHandle.stop();
        })    
    });
    

    Sur le client uniquement :

    NewPosts = new Meteor.Collection("newposts");
    
    Meteor.subscribe("newPostsPub");
    

    Cela synchronise les 10 messages les plus récents de Posts collection sur le serveur (appelée posts dans la base de données) aux NewPosts collecte sur le client (appelé newposts dans minimongo) en utilisant la publication/l'abonnement appelé newPostsPub . Notez que observeChanges diffère de observe , qui peut faire plein d'autres choses.

    Le code semble compliqué, mais lorsque vous renvoyez un curseur dans une fonction de publication, il s'agit essentiellement du code que Meteor génère en coulisses. Rédiger des publications de cette manière vous donne beaucoup plus de contrôle sur ce qui est et n'est pas envoyé au client. Attention cependant, car vous devez désactiver manuellement observe gère et marque lorsque l'abonnement est prêt. Pour plus d'informations, consultez la description de ce processus par Matt Debergalis (cependant, ce message est obsolète). Bien sûr, vous pouvez combiner cela avec les autres éléments ci-dessus pour obtenir potentiellement des publications très nuancées et compliquées.

Désolé pour l'essai :-) mais beaucoup de gens sont confus à ce sujet et j'ai pensé qu'il serait utile de décrire tous les cas.