Some of you know we are working with CouchDB quite intensively here at echolibre, and so I figured we might as well share a few of our notes, hickups, ideas, implementations, etc. So I decided to make a series of short post on CouchDB (>= 0.10.0) and I would like to start with writing your first CouchDB view in Erlang.
Obviously, you have to make sure that you enabled native Erlang views. Make sure to read on how to enabled your Erlang views on the CouchDB wiki
Once you are done, you can go into Futon and you should see “Erlang” in the list of available view languages:
Futon CouchDB
Futon CouchDB
Ok, let’s get into technicalities and the interesting stuff now, imagine you have a bunch of documents in your database and you want to get a list of documents that have a “name” and a “value” field. In javascript the view would be quite simple, it would look somewhat like:
function(doc) {
if (doc.name && doc.value) {
emit(doc.name, doc.value);
}
}
view rawcouchdb-js-view.js hosted with ❤ by GitHub
Which is perfectly fine, however in Erlang it’s a bit different, if you want to use a field, you have to make sure it’s there.
For the purpose of this post and trying to keep it short, I’ve made a rather simple view with 2 functions (fun()). 1 to validate the fields are present in the document and 1 to emit what we need.
%% Map Function
%%
%% This map function will output the doc.name as the key
%% and the doc.value as the value of that key.
%%
%% In javascript the code would look like:
%%
%% function(doc) {
%% if (doc.name && doc.value) {
%% emit(doc.name, doc.value);
%% }
%% }
fun({Doc}) ->
Emitter = fun(Doc) ->
Name = proplists:get_value(<<“name”>>, Doc, null),
Value = proplists:get_value(<<“value”>>, Doc),
Emit(Name, Value)
end,
HasRequiredFields = fun(Doc) ->
case {proplists:is_defined(<<“name”>>, Doc), proplists:is_defined(<<“value”>>, Doc)} of
{true, true} ->
%% In the second post we are going to introduce some integer validation here.
Emitter(Doc);
_->
false
end
end,
HasRequiredFields(Doc)
end.
view rawcouchdb-erl-view-001.erl hosted with ❤ by GitHub
or the compacted version:
%% Map Function
%% Thanks to Adam Kocoloski (@kocolosk) for this compacted version
fun({Doc}) ->
case {proplists:get_value(<<“name”>>, Doc), proplists:get_value(<<“value”>>, Doc)} of
{undefined, _} ->
ok;
{_, undefined} ->
ok;
{Name, Value} ->
Emit(Name, Value);
_ ->
ok
end
end.
view rawcouchdb-erl-view-002.erl hosted with ❤ by GitHub
Go to Futon’s temp view editor, select language Erlang, paste the previous code, click on Save and save your view.
Go to Futon’s temp view editor, select language Javascript, paste the javascript code above, click on Save and save your view.
They should both return the same output and you now have your first Erlang view working 🙂
Note that if you want to have a reduce function, this map function has a major flaw. I’ll point it out with an explanation in the second post regarding CouchDB Map/Reduce functions
Special thanks to Adam Kocoloski from Cloudant for the peer review and compact version of the Erlang map function and Jan Lehnardt from Couchio for the general help with Erlang views







