2017-08-30 5 views
0

Ceci est mon fichier publish.js dans lequel je publie ma collection:Trier et limite ne fonctionne pas avec Mongo + Meteor

const tags = Tags.find({title: { 
     $regex: `.*${searchString}.*`, 
     $options: 'i' 
    }}, { 
     sort: { counts: -1 }, limit: 3 
    }); 
    console.log(tags.count()); 

    return tags; 

Et voici mes composants qui abonnent à cette collection:

this.tagsSubscription = this.subscribe('tags',() => [this.tag], function (err) { 
    that.tags = Tags.find().fetch(); 
}); 

Donc, avec cela, je reçois 2 erreurs différentes:

  • le tri et la limite ne fonctionnent pas: parfois g et plus de 3 résultats et il n'y a pas trié par 'nombre'

  • le rappel ne fonctionne pas correctement. C'est trop rapide, j'ai des résultats différents sur le client et le serveur. J'ai essayé de cette façon, onSuccess() et avec Meteor.autorun() mais sans chance. Si j'utilise un setTimeout je peux voir le curseur correct

La recherche de titre est la seule chose qui semble fonctionner.

Répondre

2

Tout d'abord, selon documentation, .count() ignore les effets de .skip() et .limit(), ainsi, par exemple, si vous avez 100 dossiers au total, et vos options de requête a { limit: 3 } puis .count() pour ce curseur retournera 100 au lieu de 3. Ensuite, en regardant votre code, je suppose que votre publication attend au moins un argument: searchString. Mais votre code qui y souscrit ne le passe pas. Je pense que ce devrait être comme ça:

Meteor.subscribe('tags', this.tag,() => { 
    that.tags = Tags.find().fetch(); 
}); 

Et enfin, le tri côté serveur ne modifier les documents de tri dans les collections côté client.

Par exemple, supposons que vous avez trouvé requête comme { num: { $gte: 1 } } et il y a 3 documents qui satisfont à cette condition, avec num s égale 3, 2 et 1 en conséquence. Ces 3 documents seront envoyés à la collection des clients de cette publication.

Maintenant, ajoutons un nouveau document à cette collection mongo, avec num: 2.5. Que se passera-t-il, étant donné que vous avez { limit: 3 } comme options de requête? La publication enverra au client: removed événement pour document avec num: 1 et added événement pour document avec num: 2.5. Et la collecte côté client aura des documents dans cet ordre: 3, 2, 2.5. Par la suite, il devrait être compréhensible que vous devriez trier vos documents du côté client. Donc, dans mon code ci-dessus, il devrait être:

that.tags = Tags.find({}, { sort: { counts: -1 } }).fetch(); 

En outre, un coup d'oeil à documentation regarding what happens when publication arguments are changed.

+0

1- Intéressant, merci de clarifier. Je vois maintenant la sortie correcte sur le serveur MAIS si j'envoie une chaîne vide le client affiche 4 résultats (le serveur juste 3). Peut-être lié à un problème de rappel? 2- Oui, comme indiqué ci-dessus cela fonctionne.J'envoie "this.tag" qui est une chaîne (searchString sur le serveur). J'ai essayé le vôtre mais j'ai cette erreur: "Erreur: l'argument 2 doit être une fonction" (mais ne vous inquiétez pas à ce sujet) 3- Wow, j'ai copié cette information à partir de la documentation angulaire-météore: S Tri sur le client mais ne fonctionne pas. Ce n'est pas un gros problème, car je peux le trier avec AngularJS –

+0

Je ne comprends pas vraiment ceci: "C'est une raison très importante pour laquelle vous devriez toujours aller chercher les mêmes données que vous avez souscrites (ne pas" sur- chercher ")." Que signifie avec "les mêmes données". N'est-ce pas toujours la même chose? Certainement les problèmes que j'ai avec la taille du curseur sur le client est lié à cela. Je vais vous donner une solution de contournement –

+0

Je soupçonne que votre collection côté client n'est pas effacée lorsque vous vous réabonnez avec différents arguments, de sorte que vous pouvez également ajouter le filtrage au côté client, ainsi que le tri/la limitation. De cette façon, il devrait fonctionner sans problèmes. – Styx