Wednesday, August 18, 2010

CouchDB: Using List Functions to sort Map/Reduce-Results by Value

I just found out that it is possible to sort the result of Map/Reduce with a list function.

Let's take the simple example that you want to count all documents grouped by a field called type. The following map function emits the values of the type fields of all documents:

function(doc) {
  emit(doc.type, 1);
}

To sum up the documents with the same value in the type field, we just need this well-known reduce function:

function(key, values) {
  return sum(values)
}
By default CouchDB yields the result ordered by the keys. But if you want to order the result by occurrences of the type of the document you either have to sort it in your app or you use a list function like this:
function(head, req) { 
  var row
  var rows=[]
  while(row = getRow()) { 
    rows.push(row)  
  } 
  rows.sort(function(a,b) { 
    return b.value-a.value
  }) 
  send(JSON.stringify({"rows" : rows}))
}
If you save the list function as sort and the Map/Reduce-functions as count together in a design document, you can fetch your sorted result like this:
curl http://.../design-doc/_list/sort/count?group=true

Of course there are other options to sort a view result. I didn't found much documentation on this topic, but this thread at stackoverflow is very informative.

Back to the couch - Cheers!

Thursday, August 5, 2010

jQuery meets CoffeeScript

Disclaimer: This article is pretty old.


I'm just amazed how brilliant jQuery and CoffeeScript are working together. JQuery promises "write less, do more", but with the clean syntax of CoffeeScript you can be even more concise!

Here is a quick example:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
  <title>jQuery meets CoffeeScript</title>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
    <script src="http://jashkenas.github.com/coffee-script/extras/coffee-script.js"></script>
  
    <script type="text/coffeescript">

      show_message = (msg) -> 
        $('#message').hide().text(msg).fadeIn(2222, 
          -> $('#message').append('!') 
        )
              
      $ -> show_message "world"
      $('#message').click -> show_message "you"
      
    </script>

</head>
<body>
  <h1>hello <span id="message"></span></h1>
</body>
</html>

Here you see it running. Just click "world" to fire the click event.

hello

Just have a look to the JavaScript version:

var show_message = function(msg) {
  return $('#message').hide().text(msg).fadeIn(2222, function() {
    $('#message').append('!');
  });
};
$(function() {
  show_message("world");
});
$('#message').click(function() {
  show_message("you");
});
Happy coding!