How to check if the User Voted a Post without publishing all the Voters?


#1

Hey,
Lets assume there is a Post publication with a schema like this:

const post = {
  _id: "..."
  text: "...",
  votes: 12,
  voted: ["userId100", "userId222", ...]
};

I have to publish the voted array if I want to check if the user is in the voted array,
it is okay if only a few people voted it, but what if there is a post with 1000 votes?

The problem is if a new user vote this post, the server publishes again the whole voted array now with 1001 string inside it.

This can grow to hundreds of KBs, and publishing big data with WebSocket every sec maybe not a very good idea.

Is there any way to check if the user Voted a Post without publishing the whole Voted array?

If I would use this.userId in the publication to get a boolean if it is inside the voted array, then this would become a custom publication, and I would lose all the caching etc.

Do anyone know a good way to check if a user voted without publishing all the voters and without a custom publication?


#2

I tried to use this.changed() inside the publication but it does more issues than before.


#3

I would create a new Votes-Collection with

const vote = {
   postId: ...
   userId: ...
}


#4

Use a server-side Meteor.call() wherein you do a Collection.findOne() on a collection, and simply return true/false from that call.

Then you can create a VotesCollection which you don’t have to publish completely.

In fact, you could still use your original Post publication. You simply don’t publish the voted-array with it, though.

Edit: You could also create a Votes collection which only has the postIDs from the user himself in it. Does not fulfill your “no custom publications” criterium, however.


#5

Thanks this is a great idea!
But calling a method and do some DB work after a Post appear is looking too much work for the server isn’t it?


#6

I don’t get it, why would you publish array of votes if you don’t use them?
As stated, you may just return a true/false through aggregation on server.

Yet, 1000 user array is about(less) 20 kb non-compressed.
Subscriptions aren’t updated that frequent to make it a problem.

I feel like you’re getting too much overhead on optimization here.


And yeah, you may store array of postIDs he liked inside user document btw.
So you can show him the posts he liked and always only send an array once for individual user.


#7

Naw, the server has to do the work anyway, what with all the subscriptions updating :slight_smile:

That would probably the easiest.