Hi Couchbase community
I am trying to implement a voting system in Android where users can vote for the images they like. Unfortunately I have no idea how I would go about handling concurrent users voting at the same time. Based on my experience once documents are synced with the server the latest update will overwrite the old ones. In my case I want to add up the votes given by my user.
At the moment, I am thinking of simply updating the field that contains the data i.e. when a user votes, vote field will have its content incremented by 1 but what if another user makes his vote I’m thinking he may increment the old data and not the latest one.
I have also thought about storing the names of the images that a user has voted for in a document but it sounds like adding up the votes for each image will burn a lot of mobile resources as I have to map the image name and count it via reduce to get the total votes. Correct me if im wrong but, If I have 1000 images then I would have to perform MapReduce a thousand times which I believe will burn a lot of mobile device’s CPU.
Has anyone stumbled upon this and figured a working solution?
Thanks, sorry for being vague
Some thoughts to further the discussion.
- Updates don’t overwrite previous ones. Make sure you understand how revisions work.
There is once exception that could apply in your case. If two sources update a document with identical information, it will look to the system like they both have the same version already. So if you had a vote document that only had a vote field you updated, this could be an issue.
- Tallying votes on a mobile device that’s a client sounds like a recipe for significant headaches to me.
I haven’t totally thought it through, but a voting system like this seems like it would be much easier to implement as a server side app. Take a look at the documentation here and this blog post for some inspiration.
We built a system like this a few years ago as a demo — I’m not sure if it’s still available. It was a massively multiplayer checkers game, where anyone could vote on what move to make next and the game would make the move that got the most votes.
The way to do this is to keep each user’s votes separate. You vote by creating a document with your votes in it. Then use map/reduce to tally the votes.
If I have 1000 images then I would have to perform MapReduce a thousand times
No, you just have to query once. Here’s a sketch of how it works:
- Create a view whose map function responds to a vote document by emitting the ID of each item the user voted for. (i.e. it calls emit() once for each item, with the item as the key. The value is irrelevant; could be null.)
- The reduce function of the view simply returns the number of values.
- Now query the view with groupLevel=1 and no startKey or endKey. What you’ll get is every row has the item ID as the key and the number of votes it got as the value.
Thanks guys, interesting suggestions.
I’ll give these a try and I’ll see what I can come up with.