Both MongoDB and CouchDB are document-oriented datastores. They both work with JSON documents. They both are usually thrown into the NoSQL bucket. They’re both hip. But that’s where the similarities, for the most part, stop.
When it comes to queries, both couldn’t be any more different. CouchDB requires pre-defined views (which are essentially JavaScript MapReduce functions) and MongoDB supports dynamic-queries (basically what you’re used to with normal RDBMS ad-hoc SQL queries). What’s more, when it comes to queries, CouchDB’s API is RESTful, while MongoDB’s API is more native — that is, you essentially issue a query using a driver in the code of your choice.
For example, with CouchDB, in order to insert some data, I can use a tool like Groovy’s RESTClient and issue a RESTful post like so:
import static groovyx.net.http.ContentType.JSON
import groovyx.net.http.RESTClient
def client = new RESTClient("http://localhost:5498/")
response = client.put(path: "parking_tickets/1234334325",
contentType: JSON,
requestContentType: JSON,
body: [officer: "Robert Grey",
location: "199 Castle Dr",
vehicle_plate: "New York 77777",
offense: "Parked in no parking zone",
date: "2010/07/31"])
Note, in this case, I have to delineate a ID for this parking ticket (1234334325) (I can, incidentally, ask CouchDB for a UUID too by issuing an HTTP GET to the /_uuids path).
If I wish to find all tickets issued by Officer Grey, for example, I must define a view. Views are simply URLs that execute JavaScript MapReduce functions. Accordingly, I can quickly code a function to grab any document whose officer property is “Robert Grey” like so:
function(doc) {
if(doc.officer == "Robert Grey"){
emit(null, doc);
}
}
I have to give this view a name; consequently, when I issue an HTPP GET request to that view’s name, I can expect at least one document:
response = client.get(path: "parking_tickets/_view/by_name/officer_grey",
contentType: JSON, requestContentType: JSON)
assert response.data.total_rows == 1
response.data.rows.each{
assert it.value.officer == "Robert Grey"
}
In summary, with CouchDB, I can’t quickly issue an ad-hoc RESTful call to obtain some bit of information — I must first define a query (aka view) and then expose it to the outside world. In contrast, MongoDB works much like you’ve been used to with normal databases: you can query for what ever your heart desires at runtime.
For example, I can add the same instance of a parking ticket using MongoDB’s native Java driver (there are better options for working with MongoDB, by the way) like so:
DBCollection coll = db.getCollection("parking_tickets");
BasicDBObject doc = new BasicDBObject();
doc.put("officer", "Robert Grey");
doc.put("location", "199 Castle Dr");
doc.put("vehicle_plate", "New York 77777");
//...
coll.insert(doc);
I can subsequently find any ticket issued by Officer Robert Smith by simply issuing a query on the officer property like so:
BasicDBObject query = new BasicDBObject();
query.put("officer", "Robert Smith");
DBCursor cur = coll.find(query);
while (cur.hasNext()) {
System.out.println(cur.next());
}
Thus, while both document-oriented datastores have some similarities, then it comes to querying, they are vastly different. CouchDB requires the usage of MapReduce while MongoDB allows for more dynamically oriented queries (MongoDB also supports MapReduce). Can you dig it?