KingFu
KingFu

Reputation: 1358

CouchDB reduce function useful in this scenario?

I want to store votes in CouchDB. To get round the problem of incrementing a field in one document and having millions of revisions, each vote will be a seperate document:

{
  _id: "xyz"
  type: "thumbs_up"
  vote_id: "test"
}

So the actual document itself is the vote. The result I'd like is basically an array of: vote_id, sumOfThumbsUp, sumOfThumbsDown

Now I think my map function would need to look like:

if(type=="thumbs_up" | type =="thumbs_down"){
    emit(vote_id, type)
}

Now here's the bit I can't figure out what to do, should I build a reduce function to somehow sum the vote types, keeping in mind there's two types of votes.

Or should I just take what's been emited from the map function and put it straight into an array to work on, ignoring the reduce function completely?

Upvotes: 1

Views: 52

Answers (1)

Dominic Barnes
Dominic Barnes

Reputation: 28429

This is a perfect case for map-reduce! Having each document represent a vote is the right way to go in my opinion, and will work with CouchDB's strengths.

I would recommend a document structure like this:

Documents

UPVOTE

{
  "type": "vote",
  "vote_id": "test",
  "vote": 1
}

DOWNVOTE

{
  "type": "vote",
  "vote_id": "test",
  "vote": -1
}
  • I would use a document type of "vote", so you can have other document types in your database (like the vote category information, user information, etc)
  • I kept "vote_id" the same
  • I made the value field called "vote", and just used 1/-1 instead of "thumbs_up" or "thumbs_down" (really doesn't matter, you can do whatever you want and it will work just fine)

View

Map

function (doc) {
    if (doc.type === "vote") {
        emit(doc.vote_id, doc.vote);
    }
}

Reduce

_sum

You end up with a result like this for your map function:

map results

And if you reduce it:

reduce results

As you add more vote documents with more vote_id variety, you can query for a specific vote_id by using: /:db/_design/:ddoc/_view/:view?reduce=true&group=true&key=":vote_id"

Upvotes: 2

Related Questions