To start off, here are the links to my previous posts about CouchDB:
- Relaxing on the Couch(DB)
- Installing the Couch(DB)
- PUTting the Couch(DB) in Your Living Room
- GETting Documents From CouchDB
- DELETE Documents From CouchDB
- Adding Attachments to a Document in CouchDB
- Views into CouchDB
I briefly mentioned ‘design documents‘ in my previous post as the way views are being stored in CouchDB. This is probably the most common use of design documents, but there’s more. One thing that’s interesting is the ability of performing validation. Now before anyone starts raving like a mad man, I’m not implying that all validation or, to make matters even worse, that business rules should now all be handled by CouchDB, let along they should all be written in JavaScript from now on. In fact, quite the contrary.
But one concern that comes to mind that might be interesting for its use is validating the structure of a document.
As you might have noticed from my previous posts, we always dealt with one type of object. But a hello-real-world application typically has a domain where multiple types of objects need to be persisted. With an RDBMS, we usually have separate tables to store these different kinds of objects. CouchDB on the other hand only has the notion of storing documents. Now suppose, we need to store both Customer objects and Order objects (every application needs those, right?). How would we deal with that in CouchDB?
Well, very simple. We’ll just add a Type field to every document.
{ "Type" : "Customer" "FirstName" : "Homer" "LastName" : "Simpson" } { "Type" : "Order" "Supplier" : "Duff" "Subject" : "Sweet, sweet beer" }
Just common sense. In order to get a list of all orders, we could provide the following map function:
function(doc) { if(doc.Type != "Order") return true emit(null, doc); }
Piece of cake. Now we can use the validation capabilities of CouchDB to ensure that every document that is stored contains a Type attribute. They way to handle this is to create a design document that contains an attribute named ‘validate_doc_update’ that specifies a validation function of the following signature:
function(newDoc, oldDoc, userCtx)
{}
Now in order to keep clear of documents that specify no Type attribute, we could write the following function:
function(newDoc, oldDoc, userCtx) { if(!newDoc.Type) { throw( { "Error" : "Documents need a type around here." }); } }
Every time a document is saved or updated, CouchDB will call every validation function that is stored in a design document with the key ‘validate_doc_update’. When every function passes, the document will be stored. Otherwise, CouchDB will return HTTP status 403 (Forbidden) with a JSON response that contains the error we specified in the validation function.
As you an see, CouchDB provides you with a nice and easy to use validation mechanism that can be useful in a couple of scenarios.
Till next time
I guess it’s a style question. I prefer
function(doc) {
if(doc.type == “foo”) {
emit(doc.key, doc.value);
}
}
over the return. plus, leaving out curly braces is plain evil 🙂
Personally I am a fan of keeping the concept of tables (“collections”) around for JSON-style stores. In MongoDB, which like Couch is document-oriented, there is the concept of collections – one would have an orders collection and customers collection. I still find that model useful when I write db apps. It is still schemaless in the sense that the objects in the collections can have any desired fields — for example one could just have a “things” collection there and dump everything in it as above. One nice side effect is that objects of the same “type” are grouped together physically on disk which can be good for performance in certain circumstances too; I guess in theory CouchDB could do this internally by being very smart.
p.s I am a committer on mongodb and have my biases…check both out for yourself, right tool for the right job.
@dm: Thx for the suggestion. I’ve already picked up some of the noice about other document DBs, including mongodb. Interesting to hear about “collections” – indeed a very interesting feature. Being new to document databases in general, I’ll definitely have a look at mongodb as well.