How to convert meters to post?

I'm developing a forum on the similarity Stackowerflow and I want to consult you how best to store counters: the number of evaluations, views and selecting the best answer.

I am using Nodejs/MongoDB. Now I have two collections:


 _id: ObjectId(1),
 title: 'Untitled',
 content: 'empty'


 _post: ObjectId(1),
 _user: ObjectId(...),
 vote: 1, 
}, {
 _post: ObjectId(1),
 _user: ObjectId(...),
 vote: 1,

When a user votes for a post with ObjectId(1), then sent the following query:

Votes.create({username: ObjectId(1), vote: 1}).exec(cb);

Upon receipt of the list of posts I have to do multiple queries:

1. To query all posts sorted by creation date
2. Request all of assessment for each post and add them to the posts in nodejs.

If you frequently query the list of posts will be permanent problems in terms of counters, I'd like to improve by recounting the saving of the counter directly in the post:

 _id: ObjectId(1),
 title: 'Untitled',
 content: 'empty',
 votes: 2

But in this case I need to maintain the integrity of the data and guaranteed to update the relevant counters in the post on the basis of these estimates Votes.

This problem can be solved by embedding assessments in the form of an array and store it in the posts, but MongoDB doesn't like to update large documents.

In General advise a pattern for guaranteed recalculate counters in the post that you can use, queues, versioning, or something else?
July 9th 19 at 13:20
1 answer
July 9th 19 at 13:22
I would have thought about this option (posts):
 votes: 15,
 vote: {
 user1: 1,
 user2: -1

One request and the conversion and protection against re-vote, and fetching in a single query.
And if 100k votes? - cesar.Muller commented on July 9th 19 at 13:25
show me the post in stackoverflow where there are 100k votes

even if they will, and if they are slow, they can be placed in a special group and treat differently
if you try to store it compactly 100k * 3байта per user = total 300KB - Bianka0 commented on July 9th 19 at 13:28
Yes max there are ~15k And how to guarantee the correct update of the counter when you say re-voting user? - Savannah_Kuvalis commented on July 9th 19 at 13:31
: this is the condition to check:

db.posts.update({'vote.user1': {$exists: false}}, {votes: {$inc: 1}})
the result can be checked was the recording or not, if not passed, it means the collision (double click)

and on the client side, the button is just not active if the user already voted (this goes in a single request by post) - Bianka0 commented on July 9th 19 at 13:34
OK, and how then to provide for such a case. The user previously voted positively, ie is `1` and now voted in the negative as `-1`. In this case we need to change the rating in the vote.user and to take away the `2` votes from votes. I understand that in one operation to do this simultaneously with the verification of winding votes will not work? - Savannah_Kuvalis commented on July 9th 19 at 13:37
: Work, you the client know that the voice changes, so do the ACC. request. - Bianka0 commented on July 9th 19 at 13:40
The problem is with two tabs open one with older information than the other - Savannah_Kuvalis commented on July 9th 19 at 13:43
the second query will not work, because does not satisfy the condition. - Bianka0 commented on July 9th 19 at 13:46

Find more questions by tags MongoDBNode.jsMongoose