The monolithic approach to CouchDB views
Imagine you have an app that created one document for each day. The docs ids are easily “2015-02-05”, “2015-02-06” and so on. Nothing could be more simple. Let’s say each day you record “sales”, “expenses” and “events”, so this a document for a typical day for the retail management Couchapp for an orchid shop:
{
"_id": "2015-02-04",
"sales": [{
"what": "A blue orchid",
"price": 50000
}, {
"what": "A red orchid",
"price": 3500
}, {
"what": "A yellow orchid",
"price": 11500
}],
"expenses": [{
"what": "A new bucket",
"how much": 300
},{
"what": "The afternoon snack",
"how much": "1200"
}],
"events": [
"Bob opened the store",
"Lisa arrived",
"Bob went home",
"Lisa closed the store"
]
}
Now when you want to know what happened in a specific day, you know where to look at.
But you don’t want only that, you want profit reports, cash flows, day profitability, a complete log of the events et cetera. Then you create one view to turn this mess into something more useful:
function (doc) {
var spldate = doc._id.split("-")
var year = parseInt(spldate[0])
var month = parseInt(spldate[1])
var day = parseInt(spldate[2])
doc.sales.forEach(function (sale, i) {
emit(["sale", sale.what], sale.price)
emit(["cashflow", year, month, day, i], sale.price)
})
doc.expenses.forEach(function (exp, i) {
emit(["expense", exp.what], exp.price)
emit(["cashflow", year, month, day, i], -exp.price)
})
doc.events.forEach(function (ev, i) {
emit(["log", year, month, day, i], ev)
})
}
Then you add a reduce function with the value of _sum
and you get a bunch of useful query endpoints. For example, you can request
/_design/orchids/_view/main?startkey=["cashflow", "2014", "12"]&endkey=["cashflow", "2014", "12", {}]