Cristian Livadaru's blog

... think again ...

CouchDB Composite Keys With Date Range

We had some performance issues with data saved in CouchDB. The issue was not couchdb, it was our code and failing to use the power of couchdb views. What we wanted to achieve is to generate a call_list for all calls to a service number. We did this by selecting all calls to that number and then in ruby code throwing out what didn’t match the Date range. The result of this was

1
2
puts Benchmark.measure { Service.test_old }
  11.840000   3.450000  15.290000 ( 19.758230)

not so much fun when we just want to get a list of the last seven days worth of calls.

The solution to this problem, assuming you are using the couch_potato gem, looks something like this:

1
2
3
4
5
view :by_service_id_and_call_start, :key => [:service_id, :call_start]

def self.find_all_by_service_between_range(service_id,start_date,end_date)
  CouchPotato.database.view(Call.by_service_id_and_call_start(startkey:[service_id,start_date.to_s],endkey:[service_id,end_date.to_s]))
end

The result of this little couchdb view is:

1
2
puts Benchmark.measure { Service.test_new }
  0.780000   0.270000   1.050000 (  1.354226)

now that’s more like it :)