You’ll notice that information about the event (it’s name, etc) and all of the votes for that event are contained within the same document. This means that every time we want to record a new vote, we need to update this document. The workflow looks like this:

If many votes arrived rapidly, our app as currently written will quickly fail. There are several reason for this, but one is that Node.js does not block during I/O. We will end up saturating our DB with concurrent reads and writes, conflicts will arise and votes will be lost. In addition, an array of phone numbers is nested inside of each voteoption object. When there are millions of votes, that is quite a lot of data to send across the wire and process in our app. So, what can we do?

Well, one solution is to decouple event data from vote data. That way when votes come in, we’re simply writing them to the DB as individual documents. We can then use the power of CouchDB map and reduce view functions to query the data that our application needs. In addition to this we will look into:

Using CouchDB’s range queries to fetch the de-coupled information on an event and its votes Using CouchDB’s _id mechanism to ensure against people voting more than once Using a reduce function to rapidly calculate the count of a vote Implementing simple caches and a flush mechanism using CouchDB’s bulk operations

Modeling one-to-many relationships

In a SQL database, modelling one-to-many relationships is trivial. You define a foreign key in the child record that points to the parent record. One of the pitfalls for people coming from RDBMS is to apply this strategy to NoSQL. In CouchDB, there are many ways to model this relationship and it depends on how you application works. In our case we are going to place use separate documents for the children. See below for a denormalized version of the document I showed you at the top of this blog post: