Incrementing counter in a document best practice


#1

Dear All,

Consider implementing Facebook Like. My case is:
I have mobile app and synch gateway to synch documents.
The mobile app gets pushed new NewsArticles. The user needs to vote them, if they like.

I thought of these options to implement it:

  1. I will create a document called NewsArticleLikes to keep the counter of likes for each NewsArticleLikes {“news_article”:“NewsArticle_1”, “owner”:"sdsd@dd.com", “counter”,1); Do not allow to synch the NewsArticleLikes from server to mobiles.Instead, mobile client fetch the latest counter value for the specific NewsArticle using REST API over the server. Then update the counter using REST PUT.
    Question A) I think, in this case, it will just overwrite the counter value with my update. I will loose updates from others?
    Question B) What if I synch the NewsArticleLikes to all mobile clients and perform the updates there using CAS feature to manage concurrent updates. Then push the NewsArticleLikes to server thru Synch Gateway. I think, that would not work because of the conflicts.

  2. I will create a new NewsArticleLikes document for each voting for an article using the REST API on the server. I will not synch those documents back to mobile app. And then I will count the number of NewsArticleLikes documents for a specific user and article. Then, calculate the total number of votes in the view. That option will create a lot of documents on the server and the mobile client has to make a REST call to server for each NewsArticle displayed which is bad for performance. I do not want to push all NewsArticleLikes documents from server to mobile as there will be thousands of documents consuming space in the mobile storage.

What is the proper way of doing this, if you consider the number of users are high (there will be update conflicts a lot) and performance is important as well?

Thx,
CK


#2

Have a document for each user that lists articles they like. That document is only visible to that user.

On the server, have a view that counts the likes for every article. Run a process that periodically queries this view and writes the counts somewhere. I’m not sure what the best place is — you probably don’t want to update every article to store its ‘like’ count, because that means users have to keep downloading the articles over and over as their counts increase. You might have a document that contains just the counts of recent articles.


#3

Thanks. That makes sense. The client app has to fetch this view to get the totals of votes and store it in a local document which belongs to user and use that document to display the votes.

Thanks again!
CK


#4

It might also make sense for the clients to query directly for votes — i.e. don’t store the votes in the CBL database, but have the client make a direct view query to the server to look up votes as articles are displayed. (Of course this would be an online-only operation.)

We don’t yet have support for letting CBL make direct view queries against the server, but it’ll be in an upcoming release (1.1 or 1.2.) It’s also not difficult to implement in an app server; just define your own API whose handler will run a query against Couchbase Server and send the results back to the app, and then write some client code to call that API.