NoSQL – MongoDB example


Goal of this example

Nowdays the NoSQL databases are very popular. If you have worked with Relational Databases before, I think you know why this is. With Relational Databases the structure must be defined in advance, so you have to use ALTER for any changes, that can’t always be handled in code, and it may very slow if tables contains a lot of datas, so it results unnecessary overhead. On the other hand, it is more difficult to reconcile the concept of the new data formats, such as JSON, with the concept of the Relational Databases.

Technology Used

  • NoSQL
  • JSON
  • MongoDB
  • Spring Data
  • Spring MVC 3.1.2
  • Maven

Techniques shown in this example

  • Basics of MongoDB/NoSQL
  • Spring 3.1 MVC: XML-Free configuration (Servlet 3.0)
  • Spring Data

First of all let me say at once that NoSQL databases aren’t a direct replacement for relational databases. They fill a gap by replacing the common need for a high performance data store that would often require many slow joins and a caching layer such as memcache to implement on a typical relational database.

Types of NoSQL datastores

Key Value stores
Examples: Tokyo Cabinet/Tyrant, Redis, Voldemort, Oracle BDB
Typical applications: Content caching
Strengths: Fast lookups
Weaknesses: Stored data has no schema
Document databases
Examples: CouchDB, MongoDb
Typical applications: Web applications
Strengths: Tolerant of incomplete data
Weaknesses: Query performance, no standard query syntax
Graph databases
Examples: Neo4J, InfoGrid, Infinite Graph
Typical applications: Social networking, Recommendations
Strengths: Graph algorithms e.g. shortest path, connectedness, n degree relationships, etc.
Weaknesses: Has to traverse the entire graph to achieve a definitive answer. Not easy to cluster.
XML databases
Examples: Exist, Oracle, MarkLogic
Typical applications: Publishing
Strengths: Mature search technologies, Schema validation
Weaknesses: No real binary solution, easier to re-write documents than update them
Distributed Peer Stores
Examples: Cassandra, HBase, Riak
Typical applications: Distributed file systems
Strengths: Fast lookups, good distributed storage of data
Weaknesses: Very low-level API
Object stores
Examples: Oracle Coherence, db4o, ObjectStore, GemStone, Polar
Typical applications: Finance systems
Strengths: Matches OO development paradigm, low-latency ACID, mature technology
Weaknesses: Limited querying or batch-update options

As you can see, you can choose from several NoSQL solutions to find the most suitable tool for your problem, but don’t forget that NoSQL isn’t a magic tool. Everything has advantages and disadvantages and by weighing, you must decide which offers the most help to solve the problem.

MongoDB (“humongous”)

MongoDB is an open source, document-oriented database designed with both scalability and developer agility in mind. Documents are JSON-like data structures stored in a format called BSON. Documents are stored in collections, each of which resides in its own database. Collections can be thought of as the equivalent of a table in an RDBMS. There are no fixed schemas in MongoDB, so documents with different “shapes” can be stored in the same collection.

(The easiest way to try out the example commands in this article is to use the online shell at the MongoDB home page)

Start the MongoDB shell:

mongo.exe

Executing without any parameters, it will connect to the default database. If you would like to use another database:

use [databasename]
--use exampledrivendb

Insert some JSON objects…

> db.test.save( { name:"Adam Korosi", dob: ISODate('1983-04-04'), children: 1})
> db.test.save( { name:"Steve Smith", dob: ISODate('1981-01-12'), children: 2})
> db.test.save( { name:"Pamela Jones", dob: ISODate('1989-10-02'), children: 0})

…and query all of them…

> db.test.find()
{ "_id" : ObjectId("5099086d3601d088fe09e471"), "name" : "Adam Korosi", "dob" :
ISODate("1983-04-04T00:00:00Z"), "children" : 1 }
{ "_id" : ObjectId("509908983601d088fe09e472"), "name" : "Steve Smith", "dob" :
ISODate("1981-01-12T00:00:00Z"), "children" : 2 }
{ "_id" : ObjectId("509908bb3601d088fe09e473"), "name" : "Pamela Jones", "dob" :
 ISODate("1989-10-02T00:00:00Z"), "children" : 0 }

…or just Pamela…

> db.test.find( {name:"Pamela Jones"})
{ "_id" : ObjectId("509908bb3601d088fe09e473"), "name" : "Pamela Jones", "dob" :
 ISODate("1989-10-02T00:00:00Z"), "children" : 0 }

…or who has min. one child…

> db.test.find( {children: {$gt: 0}})
{ "_id" : ObjectId("5099086d3601d088fe09e471"), "name" : "Adam Korosi", "dob" :
ISODate("1983-04-04T00:00:00Z"), "children" : 1 }
{ "_id" : ObjectId("509908983601d088fe09e472"), "name" : "Steve Smith", "dob" :
ISODate("1981-01-12T00:00:00Z"), "children" : 2 }

I do not think it necessary to give further details, because the documentation of the MongoDB describes it very clearly, and my goal is not to replicate it.

Spring data

Add these dependencies to your Project’s pom.xml:


		org.mongodb
		mongo-java-driver
		2.9.3



		org.springframework.data
		spring-data-mongodb
		1.1.0.RELEASE

Create a Spring Config class for MongoDB:

package org.exampledriven.mongoexample.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.MongoDbFactory;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoDbFactory;

import com.mongodb.Mongo;

@Configuration
public class SpringMongoConfig {

	public final static String DATABASE = "exampledriven";

	public @Bean
	MongoDbFactory mongoDbFactory() throws Exception {
		return new SimpleMongoDbFactory(new Mongo(), DATABASE);
	}

	public @Bean
	MongoTemplate mongoTemplate() throws Exception {

		MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory());

		return mongoTemplate;

	}
}

Declare MongoTemplate in your Controller:

@Inject
MongoTemplate mongoOperations;

Now, you can use Mongo’s operations easily:

	@RequestMapping(value = "/news.html", method = RequestMethod.GET)
	public String news(@RequestParam("id") String id, Model model) {
		News news = mongoOperations.findById(id, News.class);
		model.addAttribute("news", news);

		return "news";
	}

 

	@RequestMapping(value = "/createNews.html", method = RequestMethod.POST)
	public String handleNews(@ModelAttribute News news, Model model) {
		mongoOperations.save(news);
		model.addAttribute("news", news);

		return "news";
	}

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: