Software Development
CouchDB – Relax
Introduction
- Apache CouchDB, commonly referred to as CouchDB, is an open source database that focuses on ease of use and on being “a database that completely embraces the web”.
- It is a NoSQL database that uses JSON to store data, JavaScript as its query language using MapReduce and HTTP for an API.
- One of its distinguishing features is multi-master replication.
- Couch is an acronym for cluster of unreliable commodity hardware
- A CouchDB database lacks a schema, or rigid pre-defined data structures such as tables. Data stored in CouchDB is a JSON document(s).
- The structure of the data, or document(s), can change dynamically to accommodate evolving needs.
- CouchDB also offers a built-in administration interface accessible via web called Futon.
Main features
- Document Storage:
- CouchDB stores data as “documents”, as one or more field/value pairs expressed as JSON. Field values can be simple things like strings, numbers, or dates; but ordered lists and associative arrays can also be used. Every document in a CouchDB database has a unique id and there is no required document schema.
- ACID Semantics:
- CouchDB provides ACID semantics. It does this by implementing a form of Multi-Version Concurrency Control, meaning that CouchDB can handle a high volume of concurrent readers and writers without conflict.
- Map/Reduce Views and Indexes:
- The stored data is structured using views. In CouchDB, each view is constructed by a JavaScript function that acts as the Map half of a map/reduce operation. The function takes a document and transforms it into a single value which it returns. CouchDB can index views and keep those indexes updated as documents are added, removed, or updated.
- Distributed Architecture with Replication:
- CouchDB was designed with bi-direction replication (or synchronization) and off-line operation in mind. That means multiple replicas can have their own copies of the same data, modify it, and then sync those changes at a later time.
- REST API:
- All items have a unique URI that gets exposed via HTTP. REST uses the HTTP methods POST, GET, PUT and DELETE for the four basic CRUD (Create, Read, Update, Delete) operations on all resources.
- Eventual Consistency:
- CouchDB guarantees eventual consistency to be able to provide both availability and partition tolerance.
- Built for Offline:
- CouchDB can replicate to devices (like smartphones) that can go offline and handle data sync for you when the device is back online.
- Schema-Free:
- Unlike SQL databases, which are designed to store and report on highly structured, interrelated data, CouchDB is designed to store and report on large amounts of semi-structured, document oriented data. CouchDB greatly simplifies the development of document oriented applications, such as collaborative web applications.
- In an SQL database, the schema and storage of the existing data must be updated as needs evolve. With CouchDB, no schema is required, so new document types with new meaning can be safely added alongside the old. However, for applications requiring robust validation of new documents custom validation functions are possible. The view engine is designed to easily handle new document types and disparate but similar documents.
Installation (Ubuntu)
- Open terminal and execute
1 | sudo apt-get install couchdb -y |
- If the aptitude/apt-get installation gives an error message then couchdb might not have access to its pid file.
- Fix:
1 | sudo chown -R couchdb /var/run/couchdb |
- Need to rerun the setup script:
1 | sudo dpkg --configure couchdb |
For Verifying CouchDB, check on Futon: http://127.0.0.1:5984/_utils/index.html
*For installation on other Operating Systems – http://wiki.apache.org/couchdb/Installation
CouchDB Java Client
- Ektorp
- JRelax
- jcouchdb
- DroidCouch
- CouchDB4J
- LightCouch
CouchDB4J Example
- CouchDB4J is an updated Java library for CouchDB.
- It handles the REST style calls to the CouchDB server behind the scenes, and give you a handle on the JSON objects directly.
- CouchDB4J uses JSON-lib to handle mapping to/from JSON objects, which makes getting/setting properties on the objects very easy.
- You can even map Java objects to JSON objects and back to make the process easier.
- Example:
Structure:
CouchDBCompleteDemo.java
001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 023 024 025 026 027 028 029 030 031 032 033 034 035 036 037 038 039 040 041 042 043 044 045 046 047 048 049 050 051 052 053 054 055 056 057 058 059 060 061 062 063 064 065 066 067 068 069 070 071 072 073 074 075 076 077 078 079 080 081 082 083 084 085 086 087 088 089 090 091 092 093 094 095 096 097 098 099 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 | package com.couchdb.demo; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.List; import java.util.Map; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import org.json.simple.JSONValue; import com.fourspaces.couchdb.Database; import com.fourspaces.couchdb.Document; import com.fourspaces.couchdb.Session; import com.fourspaces.couchdb.ViewResults; public class CouchDBCompleteDemo { static Session dbSession ; static Database db; public static void main(String[] args) { String dbName = "foodb" ; createDatabase(dbName); saveDocument(getDocument( "1" , "Willian" , "J2EECOE" , "TL" , "Android" )); saveDocument(getDocument( "2" , "Joanne" , "J2EECOE" , "Developer" , "Java" )); saveDocument(getDocument( "3" , "suzzane" , "J2EECOE" , "Sr. Developer" , "Java" )); saveDocument(getDocument( "4" , "Harley" , "J2EECOE" , "Sr. Developer" , "Java" )); saveDocument(getDocument( "5" , "Julian" , "J2EECOE" , "Developer" , "Java" )); saveDocument(getDocument( "6" , "Peter" , "J2EECOE" , "Developer" , "Java" )); getTotalDocumentCount(); viewAllDocuments(); viewsDemo(); // deleteDocument("6"); // getTotalDocumentCount(); // deleteDatabase(dbName); } public static void createDatabase(String dbName){ dbSession = new Session( "localhost" , 5984 ); db = dbSession.createDatabase(dbName); if (db== null ) db = dbSession.getDatabase(dbName); } public static Document getDocument(String id,String name,String group,String designation,String language){ Document doc = new Document(); doc.setId(id); doc.put( "EmpNO" , id); doc.put( "Name" , name); doc.put( "Group" , group); doc.put( "Designation" , designation); doc.put( "Language" , language); return doc; } public static void saveDocument(Document doc){ try { db.saveDocument(doc); } catch (Exception e) { } } public static int getTotalDocumentCount(){ int count = db.getDocumentCount(); System.out.println( "Total Documents: " + count); return count; } public static void deleteDocument(String id){ Document d = db.getDocument(id); System.out.println( "Document 1: " + d); db.deleteDocument(d); } public static void deleteDatabase(String dbName){ dbSession.deleteDatabase(dbName); } public static void viewAllDocuments(){ ViewResults results = db.getAllDocuments(); List<Document> documentsList = results.getResults(); if (documentsList!= null ) { for (Document doc : documentsList) { System.out.println(doc.get( "id" ) + " : " + doc); } } } public static void viewsDemo(){ if (db!= null ) { Document doc = null ; try { doc = db.getDocument( "_design/couchview" ); } catch (Exception e1) { doc = null ; } try { if (doc== null ) { doc = new Document(); doc.setId( "_design/couchview" ); String str = "{\"javalanguage\": {\"map\": \"function(doc) { if (doc.Language == 'Java') emit(null, doc) } \"}, \"java_and_se\": {\"map\": \"function(doc) { if (doc.Language == 'Java' & doc.Designation == 'SE') emit(null, doc) } \"}}" ; doc.put( "views" , str); db.saveDocument(doc); } } catch (Exception e) { } } try { DefaultHttpClient httpclient = new DefaultHttpClient(); HttpResponse response = httpclient.execute(get); HttpEntity entity=response.getEntity(); InputStream instream = entity.getContent(); BufferedReader reader = new BufferedReader( new InputStreamReader(instream)); String strdata = null ; String jsonString = "" ; while ( (strdata =reader.readLine())!= null ) { // System.out.println(strdata); jsonString += strdata; } System.out.println( "Json String: " + jsonString); Map<String, Object> jsonMap = getMapFromJsonString(jsonString); if (jsonMap!= null ) { System.out.println( "total_rows: " + jsonMap.get( "total_rows" )); System.out.println( "offset: " + jsonMap.get( "offset" )); List<Map> rowsList = (List<Map>) jsonMap.get( "rows" ); if (rowsList!= null ) { for (Map row: rowsList) { System.out.println( "----------------" ); System.out.println( "Id: " + row.get( "id" )); System.out.println( "Value: " + row.get( "value" )); System.out.println( "Name: " + ((Map)row.get( "value" )).get( "Name" )); System.out.println( "_id: " + ((Map)row.get( "value" )).get( "_id" )); System.out.println( "Language: " + ((Map)row.get( "value" )).get( "Language" )); System.out.println( "EmpNO: " + ((Map)row.get( "value" )).get( "EmpNO" )); System.out.println( "Designation: " + ((Map)row.get( "value" )).get( "Designation" )); System.out.println( "Group: " + ((Map)row.get( "value" )).get( "Group" )); } } } } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IllegalStateException e) { e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static Map<String, Object> getMapFromJsonString(String jsonString){ Map<String, Object> jsonMap = (Map<String, Object>) JSONValue.parse(jsonString); System.out.println( "Json Map: " + jsonMap); return jsonMap; } } |
I could compile but having a runtime error. I tried with all possible lib in classpath. nothing worked.
Exception in thread “main” java.lang.NoClassDefFoundError: org/apache/commons/httpclient/methods/RequestEntity
at CouchDBCompleteDemo.createDatabase(CouchDBCompleteDemo.java:73)
at CouchDBCompleteDemo.main(CouchDBCompleteDemo.java:43)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.httpclient.methods.RequestEntity
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
… 2 more