15

I'm storing location data in Couchdb, and am looking for a way to get an array of just the values, instead of key: value for every record. For example:

The current response

{"total rows": 250, "offset": 0, "rows":[
    {"id": "ec5de6de2cf7bcac9a2a2a76de5738e4", "key": "user1", "value": {"city": "San Francisco", "address":"1001 Bayhill Dr"},
    {"id": "ec5de6de2cf7bcac9a2a2a76de573ae4","key": "user1", "value": {"city": "Palo Alto", "address":"583 Waverley St"}
    ... (etc).
]}

I only really need:

[{"city": "San Francisco", "address":"1001 Bayhill Dr"},
 {"city": "Palo Alto", "address":"583 Waverley St"},
 ...]

The reason for all this is to minimize the amount of bandwidth that a JSON response consumes. I can't seem to find a way to transform the view into a simple array. Any suggestions?

Thanks.

dreftymac
  • 31,404
  • 26
  • 119
  • 182
Dick
  • 1,228
  • 13
  • 21

1 Answers1

19

You can use _show and _list functions, they take either a document or a view (respectively) and can send back a transformed response in whatever format you need. (in this case, JSON)

Update: I ran a simple test with the data you provided here on my own CouchDB. Here's the list function I ended up writing. Customize it to fit your needs. :)

function (head, req) {
    // specify that we're providing a JSON response
    provides('json', function() {
        // create an array for our result set
        var results = [];

        while (row = getRow()) {
            results.push({
                city: row.value.city,
                address: row.value.address
            });
        }

        // make sure to stringify the results :)
        send(JSON.stringify(results));
    });
}
Dominic Barnes
  • 28,083
  • 8
  • 65
  • 90
  • Great, thanks! I hadn't really looked at show/list functions yet since the Couchdb wiki suggests that their main purpose is to serve HTML directly (I was wrong). Btw, do you have an idea of the performance impact of using a show/list like this? I'll run some benchmarks myself as well. – Dick Feb 09 '11 at 23:37
  • I don't have any numbers on hand. It'll probably be faster (in general) than templating on the browser-side. Also, the built-in ETag support is a great caching mechanism to leverage. – Dominic Barnes Feb 10 '11 at 03:48
  • 2
    You could also send JSON within the while loop. Then send something before and after the loop to make it a valid JSON (and comma separate the objects). Basically, send() can be called as times as you want and not just at the end of the function. – mikeycgto Jun 24 '11 at 18:56
  • I did it with `"function (head, req) { provides('json', function() { var results = []; while (row = getRow()) { results.push(row.value); } send(JSON.stringify(results)); });}"` . – Yuseferi Nov 18 '16 at 07:01