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
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:j="http://java.sun.com/jsp/jstl/core"> <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
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:j="http://java.sun.com/jsp/jstl/core"> <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
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
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
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
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:j="http://java.sun.com/jsp/jstl/core"> <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