Couch DB



Overview


  • Document Database
  • RESTful interface
  • Horizontally scalable
  • Eventually consistent
  • MVCC (Multi Value Concurrency Control)
  • Incremental Map-Reduce

Architecture

  • Written in Erlang for concurrency
  • Horizontally scalable with painless replication
  • Supports data sharding with filters/partitioning
  • Mobile versions in development (see links)
  • Eventually consistent
    • Uses document revisions to support MVCC
    • Conflicting versions tagged, resolved in application
  • B-Tree indexing for fast lookups

Interface

  • Data definition/manipulation/retrieval via REST
  • JSON based data
  • Built in web management interface

Design Documents


  • View Functions
  • Update Functions
  • Validation Functions
  • Show Functions
  • List Functions
  • Filter Functions

VIew Functions

  • Javascript Map/Reduce
  • Incremental Modified B-Tree Indexes
  • Indexes updated on query
    • Can write service to periodically query
  • Avoid emitting full doc for efficiency

function(doc){
  if (!doc.tags || !isArray(doc.tags) || !doc.type || doc.type != 'post'){
    return;
  }
  for (var idx in doc.tags){
    emit(doc.tags[idx].toLower(), 1);
  }
}

Update Functions

  • Modify values without retrieving document
  • Automatically updates latest version
  • Custom update functionality

function(doc, req){
    if (!doc){
        if ('id' in req){
            // create new document
            return [{'_id': req['id']}, 'New World']
        }
        // change nothing in database
        return [null, 'Empty World']
    }
    doc['world'] = 'hello';
    doc['edited_by'] = req['userCtx']['name']
    return [doc, 'Edited World!']
}

Validation Functions

  • One function per design document
  • All validation functions run on all docs when saved
  • Can be used to enforce write once/read only values
  • Useful for access control
  • Perform schema validation

 function(newDoc, oldDoc, userCtx, secObj){
    function require(field, message){
        message = message;
        if(!newDoc[field]){throw({forbidden: message})}
    }
    if(newDoc.doc_type == "Command"){
        require("name");
        require("command");
    }
    if(oldDoc && oldDoc.doc_type == ("Command" || "Host") && newDoc.name != oldDoc.name){
        throw({forbidden: 'The host name cannot be changed'});
    }
}

Show Functions

  • Used to perform transforms on data
  • Can render HTML templates and serve from CouchDB
  • Can return data without requiring an existing document

function(doc, req){
  if (doc){
    return "Hello from " + doc._id + "!";
  } else {
    return "Hello, world!";
  }
}

List Functions

  • Similar to show functions
  • Operates on the results of a view

function(head, req){
  start({
    'headers': {
      'Content-Type': 'text/html'
    }
  });
  send('<html><body><table>');
  send('<tr><th>ID</th><th>Key</th><th>Value</th></tr>')
  while(row = getRow()){
    send(''.concat(
      '<tr>',
      '<td>' + toJSON(row.id) + '</td>',
      '<td>' + toJSON(row.key) + '</td>',
      '<td>' + toJSON(row.value) + '</td>',
      '</tr>'
    ));
  }
  send('</table></body></html>');
}

Filter Functions

  • Used to process the _changes feed
  • _changes feed signals any time a document changes
  • Allows for monitoring of specific modifications

function(doc, req){
  // we need only `mail` documents
  if (doc.type != 'mail'){
    return false;
  }
  // we're interested only in `new` ones
  if (doc.status != 'new'){
    return false;
  }
  return true; // passed!
}

Changes Feed

  • Lists all changes made to database
  • Use filter functions to seek relevant changes
  • Set start point for feed
  • All changes listed in sequence

Some Tricks

  • Set document type to differentiate data
  • Enforce uniqueness by assigning to an ID
    • Hash unique field with document type
  • Use validation functions to enforce minimum schema
    • Eliminates need to do value checking in application
  • Take advantage of show/list functions to do transformations

Links

Mobile Servers for iOS and Android

CouchDB

By blarghmatey

CouchDB

  • 867