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
- 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
CouchDB
By blarghmatey
CouchDB
- 867