An introduction to #CouchDB
        Sit back and relax




    @davidcoallier, University Limerick 2010
WTF IS COUCH?
- Highly concurrent database server
- Schema free, document based database
- RESTFul API
- Map/Reduce Views generation
- EASY replication (like... really)
... AGAIN.. WTF?!
HISTORY CLASS TIME!
32 CouchDB servers
                                            2 datacenters
                                   SSL based user auth, sharding, etc.




This is the only BBC transparent logo I found and it’s not BBC World News using CouchDB but BBC.
           See: http://www.erlang-factory.com/conference/London2009/speakers/endafarrell
Ubuntu One
mozilla.org
       IBM
      Apple
  myspace.com
      ebay
     meebo
oh so many more.
DOCUMENT BASED
KEY/VALUE STORE...
key       value
  name       david
  email    e@e.com
 phones      Array
createdAt timetsamp
DOCUMENT BASED WHAT?
- Dictionary of data
- JSON Objects
- A doc can have attachments
- Auto generated IDs (CLAP NOW)
- Revisions (THAT’S RIGHT..)
DOCUMENT

{
    "_id": "3fc3b3bf3c101e15fa7d08e2ecf9c900",
    "_rev": "1-34c5c7adcf1fdb8898498d1e6b64ebdd",
    "firstname": "David",
    "email": "david@echolibre.com"
}
DOCUMENT
{
    "_id": "3fc3b3bf3c101e15fa7d08e2ecf9c900",
    "_rev": "1-34c5c7adcf1fdb8898498d1e6b64ebdd",
    "firstname": "David",
    "email": "david@echolibre.com",
    "phones": {
        "mobile": "086x209x69",
        "home": "none"
    },
    "createdAt": "2009-09-16T22:12:43Z"
}
key       value
  name       david
  email    e@e.com
 phones      Array
createdAt timetsamp
WHAT ABOUT MY CRUD?

   - Create     PUT /db/docid
   - Retrieve   GET /db/docid
   - Update     POST /db/docid
   - Delete     DELETE /db/docid
VIEWS

- Persistent representation of docs
- Prod is solid. No _temp shit.
- Javascript, Erlang, Python, wtf ever.
MAP/REDUCE ...
JAVASCRIPT
MAP

map: function(doc) {
    if (doc.firstname) {
        emit(doc.firstname, doc);
    }
}
MAP
%% Map Function
fun({Doc}) ->
     case {proplists:get_value(<<"firstname">>, Doc)} of
    {undefined} ->
          false;
    {Name} ->
          Emit(Name, Doc);
     _ ->
          ok
     end
end.
fun({Doc}) ->
    Emitter = fun(Doc) ->
        Name = proplists:get_value(<<"name">>, Doc, null),

              Emit(Name, Doc)
       end,

       HasRequiredFields = fun(Doc) ->
            case {proplists:is_defined(<<"firstname">>, Doc)} of
                {true} ->
                    Emitter(Doc);
                _->
                    false
            end
       end,

       HasRequiredFields(Doc)
end.
MAP/REDUCE EXAMPLE
MAP
{
    "_id": "3fc3b3bf3c101e15fa7d08e2ecf9c900",
    "_rev": "1-34c5c7adcf1fdb8898498d1e6b64ebdd",
    "firstname": "David",
    "email": "david@echolibre.com",
    "phones": {
        "mobile": "086x209x69",
        "home": "none"
    },
    "createdAt": "2009-09-16T22:12:43Z",
    "tags": ["cool", "php", "couchdb", "skynet"]
}
MAP

map: function(doc) {
    if (doc.tags && docs.tags.length > 0) {
        for (var i = 0; i < doc.tags.length; i++) {
            emit(doc.tags[i], 1);
        }
    }
}
REDUCE
map: function(doc) {
    if (doc.tags && docs.tags.length > 0) {
        for (var i = 0; i < doc.tags.length; i++) {
            emit(doc.tags[i], 1);
        }
    }
},

reduce: function(tag, counts) {
    int sum = 0;
    for(var i = 0; i < counts.length; i++) {
        sum += counts[i];
    }
    return sum;
}
REDUCE

function(tag, counts) {
    int sum = 0;
    for(var i = 0; i < counts.length; i++) {
        sum += counts[i];
    }
    return sum;
}
REDUCE
{
    "total_rows":4,
    "rows":[
        { "key":"cool",
          "value":1},

        { "key":"php",
          "value":1},

        { "key":"couchdb",
          "value":1},

        { "key":"skynet",
          "value":1},
    ]
}
REDUCE TRICKS
map: function(doc) {
    if (doc.tags && docs.tags.length > 0) {
        for (var i = 0; i < doc.tags.length; i++) {
            emit(doc.tags[i], 1);
        }
    }
}


reduce: "_count"
REDUCE
{
    "total_rows":4,
    "rows":[
        { "key":"cool",
          "value":1},

        { "key":"php",
          "value":1},

        { "key":"couchdb",
          "value":1},

        { "key":"skynet",
          "value":1},
    ]
}
REDUCE
map: function(doc) {
    if (doc.tags && docs.tags.length > 0) {
        for (var i = 0; i < doc.tags.length; i++) {
            emit(doc.tags[i], "yer ma");
        }
    }
},

reduce: function (tag, count) {
    return sum(tag);
}
THEN...
BEWARE OF REDUCE VALUES
REPLICATION


  It fuckin’ rules.
REPLICATION

      Easy (See later futon ;-))
        Continuous... or not :P
        Replicates your views
Replicate only what you need (filter?)
REPLICATION
                   curl -X POST http://localhost:5984/_replicate 
'{"source":"/dbname", "target": "http://localhost:5555/otherdb", "continuous": true}'
REPLICATION
Source              The boss               Target

         changes?              watcha
                               need??
      target
    needs x, y, z              save them
REPLICATION
MASTER / SLAVES
REPLICATION
MASTER / SLAVES
REPLICATION
MULTI MASTER
REPLICATION
MULTI MASTER
REPLICATION
  USE CASE



    Automated job
to validate and test data
 and do bunch of shits
FUTON
FUTON
NOTE TO SELF.


   Show them.




                Open up CouchDBX
COOL THINGS
         Authorization
        CouchDB Lucene
            Lounge
          CouchDBX
           Couchio
           Cloudant

A bunch of random bits and pieces
COMPLETE SHITE COMING UP


                                                      eas
                                               r e id
                                            sha
                                        W
                                  le! NO
                                 p
                           s peo
                       cus
                   Dis
CONCEPTS AND IDEAS


      Graph Theory




                                                        ...
                                                  ss ion
                                               u
                                         a disc
                                     t
                              d star
                     tr   y an
CONCEPTS AND IDEAS


     Ghost Replication




                                                            ...
                                                      ss ion
                                                   u
                                             a disc
                                         t
                                  d star
                         tr   y an
CONCEPTS AND IDEAS


   Shared Index Replication




                                                                 ...
                                                           ss ion
                                                        u
                                                  a disc
                                              t
                                       d star
                              tr   y an
QUESTIONS?
ME! MEEE!!!


   @davidcoallier
david@echolibre.com
THANKS
LINKS

- https://nosqleast.com/2009/slides/miller-couchdb.pdf
- http://couch.io
- http://cloudant.com
- http://wiki.apache.org/couchdb/CouchDB_in_the_wild
- irc://couchdb@freenode.net (Bug jan___ ;-))

An introduction to CouchDB

  • 1.
    An introduction to#CouchDB Sit back and relax @davidcoallier, University Limerick 2010
  • 2.
    WTF IS COUCH? -Highly concurrent database server - Schema free, document based database - RESTFul API - Map/Reduce Views generation - EASY replication (like... really)
  • 3.
  • 4.
  • 6.
    32 CouchDB servers 2 datacenters SSL based user auth, sharding, etc. This is the only BBC transparent logo I found and it’s not BBC World News using CouchDB but BBC. See: http://www.erlang-factory.com/conference/London2009/speakers/endafarrell
  • 7.
  • 8.
    mozilla.org IBM Apple myspace.com ebay meebo oh so many more.
  • 9.
  • 10.
    key value name david email e@e.com phones Array createdAt timetsamp
  • 11.
    DOCUMENT BASED WHAT? -Dictionary of data - JSON Objects - A doc can have attachments - Auto generated IDs (CLAP NOW) - Revisions (THAT’S RIGHT..)
  • 12.
    DOCUMENT { "_id": "3fc3b3bf3c101e15fa7d08e2ecf9c900", "_rev": "1-34c5c7adcf1fdb8898498d1e6b64ebdd", "firstname": "David", "email": "david@echolibre.com" }
  • 13.
    DOCUMENT { "_id": "3fc3b3bf3c101e15fa7d08e2ecf9c900", "_rev": "1-34c5c7adcf1fdb8898498d1e6b64ebdd", "firstname": "David", "email": "david@echolibre.com", "phones": { "mobile": "086x209x69", "home": "none" }, "createdAt": "2009-09-16T22:12:43Z" }
  • 14.
    key value name david email e@e.com phones Array createdAt timetsamp
  • 15.
    WHAT ABOUT MYCRUD? - Create PUT /db/docid - Retrieve GET /db/docid - Update POST /db/docid - Delete DELETE /db/docid
  • 16.
    VIEWS - Persistent representationof docs - Prod is solid. No _temp shit. - Javascript, Erlang, Python, wtf ever.
  • 17.
  • 18.
  • 19.
    MAP map: function(doc) { if (doc.firstname) { emit(doc.firstname, doc); } }
  • 20.
    MAP %% Map Function fun({Doc})-> case {proplists:get_value(<<"firstname">>, Doc)} of {undefined} -> false; {Name} -> Emit(Name, Doc); _ -> ok end end.
  • 21.
    fun({Doc}) -> Emitter = fun(Doc) -> Name = proplists:get_value(<<"name">>, Doc, null), Emit(Name, Doc) end, HasRequiredFields = fun(Doc) -> case {proplists:is_defined(<<"firstname">>, Doc)} of {true} -> Emitter(Doc); _-> false end end, HasRequiredFields(Doc) end.
  • 22.
  • 23.
    MAP { "_id": "3fc3b3bf3c101e15fa7d08e2ecf9c900", "_rev": "1-34c5c7adcf1fdb8898498d1e6b64ebdd", "firstname": "David", "email": "david@echolibre.com", "phones": { "mobile": "086x209x69", "home": "none" }, "createdAt": "2009-09-16T22:12:43Z", "tags": ["cool", "php", "couchdb", "skynet"] }
  • 24.
    MAP map: function(doc) { if (doc.tags && docs.tags.length > 0) { for (var i = 0; i < doc.tags.length; i++) { emit(doc.tags[i], 1); } } }
  • 25.
    REDUCE map: function(doc) { if (doc.tags && docs.tags.length > 0) { for (var i = 0; i < doc.tags.length; i++) { emit(doc.tags[i], 1); } } }, reduce: function(tag, counts) { int sum = 0; for(var i = 0; i < counts.length; i++) { sum += counts[i]; } return sum; }
  • 26.
    REDUCE function(tag, counts) { int sum = 0; for(var i = 0; i < counts.length; i++) { sum += counts[i]; } return sum; }
  • 27.
    REDUCE { "total_rows":4, "rows":[ { "key":"cool", "value":1}, { "key":"php", "value":1}, { "key":"couchdb", "value":1}, { "key":"skynet", "value":1}, ] }
  • 28.
    REDUCE TRICKS map: function(doc){ if (doc.tags && docs.tags.length > 0) { for (var i = 0; i < doc.tags.length; i++) { emit(doc.tags[i], 1); } } } reduce: "_count"
  • 29.
    REDUCE { "total_rows":4, "rows":[ { "key":"cool", "value":1}, { "key":"php", "value":1}, { "key":"couchdb", "value":1}, { "key":"skynet", "value":1}, ] }
  • 30.
    REDUCE map: function(doc) { if (doc.tags && docs.tags.length > 0) { for (var i = 0; i < doc.tags.length; i++) { emit(doc.tags[i], "yer ma"); } } }, reduce: function (tag, count) { return sum(tag); }
  • 31.
  • 32.
  • 33.
    REPLICATION Itfuckin’ rules.
  • 34.
    REPLICATION Easy (See later futon ;-)) Continuous... or not :P Replicates your views Replicate only what you need (filter?)
  • 35.
    REPLICATION curl -X POST http://localhost:5984/_replicate '{"source":"/dbname", "target": "http://localhost:5555/otherdb", "continuous": true}'
  • 36.
    REPLICATION Source The boss Target changes? watcha need?? target needs x, y, z save them
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
    REPLICATION USECASE Automated job to validate and test data and do bunch of shits
  • 42.
  • 43.
  • 44.
    NOTE TO SELF. Show them. Open up CouchDBX
  • 45.
    COOL THINGS Authorization CouchDB Lucene Lounge CouchDBX Couchio Cloudant A bunch of random bits and pieces
  • 46.
    COMPLETE SHITE COMINGUP eas r e id sha W le! NO p s peo cus Dis
  • 47.
    CONCEPTS AND IDEAS Graph Theory ... ss ion u a disc t d star tr y an
  • 48.
    CONCEPTS AND IDEAS Ghost Replication ... ss ion u a disc t d star tr y an
  • 49.
    CONCEPTS AND IDEAS Shared Index Replication ... ss ion u a disc t d star tr y an
  • 50.
  • 51.
    ME! MEEE!!! @davidcoallier david@echolibre.com
  • 52.
  • 53.
    LINKS - https://nosqleast.com/2009/slides/miller-couchdb.pdf - http://couch.io -http://cloudant.com - http://wiki.apache.org/couchdb/CouchDB_in_the_wild - irc://couchdb@freenode.net (Bug jan___ ;-))