MongoDB and Web applications
Today’s era is when data grows at very huge scale. Data storage is not a problem, yes but the way it gets structured and stored may increase or decrease the seek time for needed data blocks.
Use Cases of ever increasing unstructured data
- Facebook:
- 750 million users are active , 1 in 3 Internet users have a Facebook account
- More than 30 billion pieces of content (web links, news stories, blog posts, notes, photo albums, etc.) shared each month.
- Holds 30PB of data for analysis, adds 12 TB of compressed data daily
- 200 million users, 200 million daily tweets
- 1.6 billion search queries a day
- 7 TB data for analysis generated daily
At these scales Traditional data storage, techniques & analysis tools do not work!
Current scenarios call for a need of NoSQL Databases like Apache Cassandra, Mongo DB to deal with such ever increasing unstructured data. NoSQL database provides looser consistency models than traditional RDBMS for storage and retrieval of data. NoSQL databases store the data as highly optimized key–value pairs, and this leads to simple retrieval and appending operations, hence increasing the performance in terms of low latency and high throughput.
NoSQL databases play a significant role in industries, where big data and real-time web applications are developed and maintained.
Use Case for Mongo DB and Web applications
Let us imagine that we want to make a Car Registration portal using JSF2.0 and Mongo DB at its back end. There will be two functionalities
- Car Registration
- To view the report of registered cars
Figure1 depicts the flow of the project that is intended to be made.
Assumptions:
- Mongo DB is already installed and running as service
- Eclipse indigo or higher version
- Tomcat 7.0 or higher version
- Required jar files are present (JSF2.0 jars jsf-api.jar,jsf-impl),mongo-java-driver-2.10.1.jar or any suitable version
Application has three pages viz: Home.xhtml, AddCar.xhtml, Report.xhtml.
Implementation of Home.xhtml goes as follow:
Home.xhtml
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | <! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> < h:head > < meta http-equiv = "content-type" content = "text/html; charset=utf-8" /> </ h:head > < h:body > < f:view > < h:form > < center > < h2 > MSD Car Portal</ h2 > < h4 > < h:outputLink value = "AddCar.xhtml" >Add Car</ h:outputLink >< br />< br /> < h:commandLink action = "#{carBean.getCarDetails}" >See Registered Cars</ h:commandLink > </ h4 > </ center > </ h:form > </ f:view > </ h:body > </ html > |
On clicking the Add Car link, AddCar.xhtml Is loaded and the following lines of code is executed.
AddCar.xhtml
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | <! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> < h:head > < meta http-equiv = "content-type" content = "text/html; charset=utf-8" /> </ h:head > < h:body > < f:view > < h:form > < center > < h2 >MSD Car Portal</ h2 > < h3 >Add a Car</ h3 > < h:panelGrid border = "2" columns = "2" > < h:outputText value = "CarName" ></ h:outputText > < h:inputText value = "#{carBean.carTO.carName}" ></ h:inputText > < h:outputText value = "Company" ></ h:outputText > < h:inputText value = "#{carBean.carTO.company}" ></ h:inputText > < h:outputText value = "Model" ></ h:outputText > < h:inputText value = "#{carBean.carTO.model}" > < f:convertDateTime pattern = "dd-MMM-yyyy" ></ f:convertDateTime > </ h:inputText > < h:outputText value = "CC" ></ h:outputText > < h:inputText value = "#{carBean.carTO.cc}" ></ h:inputText > < h:outputText value = "Price" ></ h:outputText > < h:inputText value = "#{carBean.carTO.price}" ></ h:inputText > </ h:panelGrid > < h:commandButton action = "#{carBean.addCar}" value = "Add Car" ></ h:commandButton >< br /> < h:outputText value = "#{carBean.message}" ></ h:outputText > < br />< h:outputLink value = "Home.xhtml" >Home</ h:outputLink > </ center > </ h:form > </ f:view > </ h:body > </ html > |
On clicking the Add Car button the action handler of the CarBean(backing bean) is invoked and in the backing Bean CarTO (Car Transfer Object ) is send to CarService’s insertData function, here by inserting the values of CarTO values into a document and adding the document to a collection. And on clicking Home Home.xhtml is shown. Following listing shows the code for the CarBean.
CarBean.java
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | package mongo.db.bean; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.List; import javax.faces.bean.ManagedBean; import mongo.db.service.CarService; import mongo.db.to.CarTO; @ManagedBean public class CarBean { private List<CarTO> list = new ArrayList<CarTO>(); private String message; private CarTO carTO= new CarTO(); /**Action handler to save the data in the collection*/ public String addCar(){ try { /**Inserting the data to the Service class to insert it into Mongo DB*/ message= new CarService() .insertData( "testdb" , "MyNewJAVATableCollection3" ,carTO); /**Message property is shown on the Page to show success message on the page*/ } catch (UnknownHostException e) { message= e.getMessage(); } return "samePage" ; } /**Action handler to get the data from the collection*/ public String getCarDetails(){ try { /**Reading the data From the Service class which further read the data from the Mongo DB */ list = new CarService() .findData( "testdb" , "MyNewJAVATableCollection3" ); if (list.size()== 0 ){ message= "No records Exist" ; } } catch (UnknownHostException e) { message= e.getMessage(); } return "success" ; } /*Getters and setters to be coded*/ } |
Code for the service class goes as follows:
CarService.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 | package mongo.db.service; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Calendar; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import mongo.db.to.CarTO; import com.mongodb.BasicDBObject; import com.mongodb.DB; import com.mongodb.DBCollection; import com.mongodb.DBCursor; import com.mongodb.DBObject; import com.mongodb.MongoClient; public class CarService { /**Utility to Get the Connection from the database*/ public static DBCollection getConnection(String dbName, String collectionName) throws UnknownHostException { /** Connecting to MongoDB */ MongoClient mongo = new MongoClient( "localhost" , 27017 ); /**Gets database, incase if the database is not existing MongoDB Creates it for you*/ DB db = mongo.getDB(dbName); /**Gets collection / table from database specified if collection doesn't exists, MongoDB will create it for you*/ DBCollection table = db.getCollection(collectionName); return table; } /**function to insert the data to the database */ public String insertData(String dbName, String collectionName, CarTO carTO) throws UnknownHostException { /**Connecting to MongoDB*/ DBCollection table =CarService.getConnection(dbName, collectionName); /**creating a document to store as key and value*/ BasicDBObject document = new BasicDBObject(); document.put( "carName" , carTO.getCarName()); document.put( "company" , carTO.getCompany()); document.put( "model" , carTO.getModel()); document.put( "cc" , carTO.getCc()); document.put( "Price" , carTO.getPrice()); /** inserting to the document to collection or table*/ table.insert(document); return "Car added successfully with the record number :" +table.count(); } /**function to get Details from the database*/ public List<CarTO> findData(String dbName, String collectionName) throws UnknownHostException { /**Connecting to database*/ DBCollection table= CarService.getConnection(dbName, collectionName); /**getting results from the database*/ DBCursor cursor = table.find(); List<CarTO>list= new ArrayList<CarTO>(); /**iterating over the documents got from the database*/ while (cursor.hasNext()) { DBObject obj= cursor.next(); /**documentToMapUtility is coded to convert the document received from database to key value pairs and put it inside a map*/ Map map=CarService.documentToMapUtility(obj.toString()); /**Map having values is iterated using entry set and CarTO is populated and CarTO is added in the List<CarTO> and this list returned*/ /**Getting the Entery Set from the map */ Set<Entry<String,String>> set= map.entrySet(); /**Getting the Iterator to iterate the entry Set*/ Iterator<Entry<String,String>> itr= set.iterator(); CarTO carTO = new CarTO(); /**loop to put ever Key value pair to CarTO object*/ while (itr.hasNext()){ Entry<String, String> entry = itr.next(); String key=entry.getKey(); /**Removing the unwanted from the keys*/ key = CarService.subStringUtility(key); String value=entry.getValue(); if (key.equalsIgnoreCase( "carName" )){ carTO.setCarName(value.substring( 2 ,value.length()- 2 )); } else if (key.equalsIgnoreCase( "company" )){ carTO.setCompany(value.substring( 2 ,value.length()- 2 )); } else if (key.equalsIgnoreCase( "model" )){ String date[]=value.split( "-" ); int year=Integer.parseInt(date[ 0 ].substring( 2 )); int month=Integer.parseInt(date[ 1 ]); int datemon=Integer.parseInt(date[ 2 ].substring( 0 , date.length- 1 )); Calendar c= Calendar.getInstance(); c.set(Calendar.YEAR, year); c.set(Calendar.MONTH, month); c.set(Calendar.DATE, datemon); carTO.setModel(c.getTime()); } else if (key.equalsIgnoreCase( "cc" )){ carTO.setCc(Integer.parseInt(value.trim())); } else if (key.equalsIgnoreCase( "Price" )){ carTO.setPrice(Double.parseDouble(value.trim())); } } /**inner While closed*/ list.add(carTO); } /**while iterating over the cursor records closed here*/ return list; } /**Utility to remove un wanted contents*/ public static String subStringUtility (String s){ return s.substring( 2 ,s.length()- 2 ); } /**Utility to convert the document to map*/ public static Map<String,String> documentToMapUtility (String s){ s= s.substring( 1 ,s.length()- 1 ); String sArr[]= s.split( "," ); Map<String,String> map = new LinkedHashMap<String,String>(); for ( int i= 1 ;i<sArr.length;i++){ if (!sArr[i].contains( "$date" )){ String keyValue[]= sArr[i].split( ":" ); map.put(keyValue[ 0 ],keyValue[ 1 ]); System.out.println(keyValue[ 0 ]+ "," +keyValue[ 1 ]); } else { String keyValue[]= sArr[i].split( ":" ); map.put(keyValue[ 0 ],keyValue[ 2 ]); } } return map; } } |
Following listing shows the content for the transfer object class CarTO
CarTO.java
01 02 03 04 05 06 07 08 09 10 | package mongo.db.to; import java.util.Date; public class CarTO { private String carName; private String company; private Integer cc; private Double price; private Date model; /*Getters and Setters to be coded*/ } |
On clicking the See Registered Cars link on the home page, as it is a command link action handler getCarDetails of the CarBean is executed and details are fetched from the CarService class with help of the method findData please refer the CarBean code for the action handler getCarDetails. Following listing represents the code for the Report.xhtml.
Report.xhtml.java
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | <! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> < h:head > < meta http-equiv = "content-type" content = "text/html; charset=utf-8" /> </ h:head > < h:body > < f:view > < h:form > < center > < h2 >MSD Car Portal</ h2 > < h3 >Car Details</ h3 > < h:dataTable value = "#{carBean.list}" var = "item" border = "2" rendered = "#{not empty carBean.list}" > < h:column > < f:facet name = "header" > < h:outputText value = "CarName" ></ h:outputText > </ f:facet > < h:outputText value = "#{item.carName}" ></ h:outputText > </ h:column > < h:column > < f:facet name = "header" > < h:outputText value = "Company" ></ h:outputText > </ f:facet > < h:outputText value = "#{item.company}" ></ h:outputText > </ h:column > < h:column > < f:facet name = "header" > < h:outputText value = "Model" ></ h:outputText > </ f:facet > < h:outputText value = "#{item.model.time}" > < f:convertDateTime pattern = "dd-MMM-yyyy" ></ f:convertDateTime > </ h:outputText > </ h:column > < h:column > < f:facet name = "header" > < h:outputText value = "CC" ></ h:outputText > </ f:facet > < h:outputText value = "#{item.cc}" ></ h:outputText > </ h:column > < h:column > < f:facet name = "header" > < h:outputText value = "Price" ></ h:outputText > </ f:facet > < h:outputText value = "#{item.price}" ></ h:outputText > </ h:column > </ h:dataTable > < br />< h:outputText value = "#{carBean.message}" ></ h:outputText > < br />< h:outputLink value = "Home.xhtml" >Home</ h:outputLink > </ center > </ h:form > </ f:view > </ h:body > </ html > |
Conclusion
From the given example it much clear that MongoDb can be integrated with present web frameworks and can be utilized to make web applications that can easily handle the Big Data problems
Reference:
- http://www.rabidgremlin.com/data20/
- http://docs.mongodb.org/manual/tutorial/install-mongodb-on-windows/
- http://docs.oracle.com/javaee/6/tutorial/doc/bnaph.html
Why do you always instantiate new CarService? And why for each car are you creating new MongoClient (additionaly by invoking static method)?
Dear Kuba Kubrynski;
Friend in the article we are trying to follow a design pattern, in which application is developed using persistence and presentation layers
And communication is across the layers is done using tranfer objects (TO). And required DB provider (in our case mongo client) is instantiated separately for each functionality.
When each time it is requested.
Mohpreet,
You are writing about great goodness of NoSQL performance and scalability but why are you considering to make a test application with JSF? JSF don’t have good scalability as it is a session-intensive framework. So I think this combination (JSF + MongoDB) will never perform well on any high-loaded application like twitter.
+10000 jsf is a good solution if your need to create a intranet, never for a massive distributed solution
Alex,
Could you please suggest appropriate web framework for high-loaded / scalable application ?
Anil,
Spring MVC or Grails or any other stateless web framework.
Dear Alex,
In the article we trying to address a issue how to handle big data problems in web applications, the one possible is using MongoDB at the backend , in the persistence layer of the application,
whereas presentation layer framework can be modified as per the need. it can be struts,springs wickets etc as per to the choice of the developer.
Hai,
This is venkatesh, I am developing a web application to store images into MongoDB as well as i want display on html page .
Please provide me code on jsp or servlets.
unable to run the command,please send me the zip file