Search code examples
couchdbmapreduceanalytics

couchdb - filtering on complex key


I have 30m records of the following schema in couchdb.

{ countryIso: 'TR'
, region: '68'
, city: 'Ankara'
, lat: '39.927200317383'
, lon: '32.864398956299'
, action: 'install'
, itime: 1288523291000  // That is unix timestamp
, fileId: 33221
, api_level: '3'
, display_size: '320x480'
, model: 'Galaxy'
}

These records represent downloads of files in a service. What i would like to do is provide statistics for these events.

Some example queries:

  • Given fileId and date range, get number of downloads per day
  • Given fileId and date range, get display_size's used per day
  • Given fileId and date range, get api_level used per day

Ideally (if possible) we should also answer more complex queries, like:

  • Given fileId, date range and countryIso, show downloads per day

I made the following map function

function (doc) {
  emit([doc.fileId,
        Math.floor(doc.itime/60/60/24),
        doc.countryIso, doc.display_size,
        doc.api_level], 1)
}

and _sum as the reduce function.

Now i can do this

?group_level=2&startkey=[247]&endkey=[247,{}]

{"rows":[
{"key":[247,14913505],"value":4},
{"key":[247,14913528],"value":4},
{"key":[247,14913563],"value":4}
]}

for example, to get the downloads of a specific fileId per day.

or this

?group_level=3&startkey=[247]&endkey=[247,{}]

{"rows":[
{"key":[247,14913505,"GB"],"value":4},
{"key":[247,14913528,"AE"],"value":4},
{"key":[247,14913563,"TR"],"value":4}
]}

to get the downloads of a specific fileId per day per country.

But i cant seem to query my view in a way that will return this

{"rows":[
{"key":[247,14913505,"320x480"],"value":4},
{"key":[247,14913528,"320x480"],"value":4},
{"key":[247,14913563,"320x533"],"value":4}
]}

Do i have to create a separate view for each of the queries (graphs) i need, or you think it is possible to create a complex view that will answer all these queries?


Solution

  • There's no way to slice into your keys like that, you only have lexical order to work with. So make separate views.