Alex Rivera | Logout

Emit Tuples From Erlang Views In CouchDB

Asked 2010-03-10T05:49:25.830
9

CouchDB, version 0.10.0, using native erlang views.

I have a simple document of the form:

{
   "_id": "user-1",
   "_rev": "1-9ccf63b66b62d15d75daa211c5a7fb0d",
   "type": "user",
   "identifiers": [
       "ABC",
       "DEF",
       "123"
   ],
   "username": "monkey",
   "name": "Monkey Man"
}

And a basic javascript design document:

{
   "_id": "_design/user",
   "_rev": "1-94bd8a0dbce5e2efd699d17acea1db0b",
   "language": "javascript",
   "views": {
     "find_by_identifier": {
       "map": "function(doc) {
          if (doc.type == 'user') {
            doc.identifiers.forEach(function(identifier) {
              emit(identifier, {\"username\":doc.username,\"name\":doc.name});
            });
          }
       }"
     }
   }
}

which emits:

{"total_rows":3,"offset":0,"rows":[
{"id":"user-1","key":"ABC","value":{"username":"monkey","name":"Monkey Man"}},
{"id":"user-1","key":"DEF","value":{"username":"monkey","name":"Monkey Man"}},
{"id":"user-1","key":"123","value":{"username":"monkey","name":"Monkey Man"}}
]}

I'm looking into building an Erlang view that does the same thing. Best attempt so far is:

%% Map Function
fun({Doc}) ->
    case proplists:get_value(<<"type">>, Doc) of
    undefined ->
        ok;
    Type ->
        Identifiers = proplists:get_value(<<"identifiers">>, Doc),
        ID = proplists:get_value(<<"_id">>, Doc),
        Username = proplists:get_value(<<"username">>, Doc),
        Name = proplists:get_value(<<"name">>, Doc),
        lists:foreach(fun(Identifier) -> Emit(Identifier, [ID, Username, Name]) end, Identifiers);
    _ ->
        ok
    end
end.

which emits:

{"total_rows":3,"offset":0,"rows":[
{"id":"user-1","key":"ABC","value":["monkey","Monkey Man"]},
{"id":"user-1","key":"DEF","value":["monkey",
Edit
Report

1 Answer

13

The JSON object {"foo":"bar","baz":1} is {[{<<"foo">>,<<"bar">>},{<<"baz">>,1}]}

In Erlang lingua it is a proplist wrapped in a tuple.

It's not pretty, but very efficient :)

To get a feel for it you can play with the JSON lib that ships with CouchDB:

  1. Start CouchDB with the -i (interactive) flag
  2. On the resulting erlang shell, type: couch_util:json_decode(<<"{\"foo\":\"bar\"}">>).
  3. Profit

// in later versions of CouchDB, this is ejson:decode()

answered 2010-03-11T04:56:46.510

Your Answer