Thursday, August 2, 2012

MongoDB and Java

MongoDB and Java
In this article, I would explain what MongoDB is?, how to use it with java.
MongoDB is a NOSQL database. It’s time that all data in the database would be stored in Document Oriented Storage. MongoDB is scalable, high-performance, open source NoSql database.
MongoDB supports asynchronous replication of data between servers for failover and redundancy. Only one server (in the set/shard) is active for writes (the primary, or master) at a given time – this is to allow strong consistent (atomic) operations. One can optionally send read operations to the secondaries when eventual consistency semantics are acceptable.
Two forms of replication are available, Replica Sets and Master-Slave. Use Replica Sets – replica sets are a functional superset of master/slave and are handled by much newer, more robust code.

MongoDB scales horizontally via an auto-sharding (partitioning) architecture. MongoDB sharding provides:
·         Automatic balancing for changes in load and data distribution
·         Easy addition of new machines without down time
·         Scaling to one thousand nodes
·         No single points of failure
·         Automatic failover

Starting and working on MongoDB shell
Once you install MongoDB, execute the MongoD.exe file in the bin directory. And mongo.exe file in the same directory.
You need to use Shell prompt to work with MongoDB, all commands will be issued using the shell prompt.
Connecting to database:
MongoDB by default connect to ‘test’ db, and later if you want to create/change to new db you need to use the command ‘use dbname’. DB will be created lazily when data is inserted.

From Java we can connect to the db using the following code snippet. Before that you need to download java driver for mongodb from www. Mongodb.org.
   final Mongo mongo = new Mongo();

        // or
  Mongo m = new Mongo( "localhost" );
        // or
  Mongo m = new Mongo( "localhost" , 27017 );
        // or, to connect to a replica set, supply a seed list of members
  Mongo m = new Mongo(Arrays.asList(new ServerAddress("localhost", 27017),
                                    new ServerAddress("localhost", 27018),
                                    new ServerAddress("localhost", 27019)));
  final DB db = mongo.getDB("test");

Creating a collection in MongoDB:
In mongoDB semantics a table will be referred to as collection. To create a collection we will use the following command
1.       You can directly insert a object to a collection, so that if the collection is not available MongoDB will create one.
2.       Else you can go for explicit creation of collection by

Here capped refers to capped collection, meaning fixed sized collections that have a very high performance auto-FIFO age-out feature (age out is based on insertion order). They are a bit like the "RRD" concept if you are familiar with that.
In addition, capped collections automatically, with high performance, maintain insertion order for the documents in the collection; this is very powerful for certain use cases such as logging.
Capped collections are not shard-able.

From java collection can be created by
DBObject options = BasicDBObjectBuilder.start().add("capped", true).add("size", 2000000000l).get();
        collection = db.createCollection("mytestcoll ", options);

db.getCollection("mytestcoll")

Inserting data in MongoDB:
To insert and save data , we need to use the following command in mongo shell
Db.collectionName.save(“data”);

To retrieve/find the inserted data , use the following command
Db.collectionname.find();


From java the same can by achieved using the following code snippets

  final DB db = mongo.getDB("sampledb");
        final DBCollection coll = db.getCollection("mytestcoll");
        Integer age = 27;
        String sex = "m";
        final BasicDBObject doc = new BasicDBObject();
        doc.put("name", "MongoDB");
        doc.put("age", age);
        doc.put("sex", sex);
        coll.insert(doc);

To retrieve data
  final DB db = mongo.getDB("sampledb");
  final DBCollection coll = db.getCollection("mytestcoll");
        final DBCursor results = coll.find();
        while (results.hasNext()) {
            final DBObject dbObject = results.next();
            final Object name = dbObject.get("name");
            final Object type = dbObject.get("type");
            System.out.println(name + "  :  " + type);
        }

Updating and deleteing a record from collection:
Updating a record:

To update a record in collection, you can fetch a record and assign to a variable in Javascript style and do the update as below

db.collection.update( criteria, objNew, upsert, multi )
Arguments:
criteria - query which selects the record to update;
objNew - updated object or $ operators (e.g., $inc) which manipulate the object
upsert - if this should be an "upsert" operation; that is, if the record(s) do not exist, insert one. Upsert only inserts a single document.
multi - indicates if all documents matching criteria should be updated rather than just one. Can be useful with the $ operators below.

Using java

BasicDBObject updateQuery = new BasicDBObject().append("$set",
                new BasicDBObject().append("type", "db serve"));
        
                //multi default to false
coll.update(new BasicDBObject().append("name", "mongo"), updateQuery);

To delete a record:

db.things.remove({name:”mongo”});

In java:

final BasicDBObject bdo = new BasicDBObject();
        bdo.put("name", "mongodb");
        coll.remove(coll.findOne());

MapReduce function:

Apart from this, MongoDB supports MapReduce functions, you can specify the mapper and reduce functions as string format and do the mapreduce process in MongoDb.

public class MongoMap {

    public static void main(final String[] args) throws UnknownHostException,
            MongoException {
        final Mongo mongo = new Mongo();

        final DB db = mongo.getDB("test");

        final DBCollection coll = db.getCollection("mapr");

        final String m =
                "function m() {" + "key = this.age ;"
                        + "emit( key, { count: 1 } ) ;" + "}";

        final String r =
                "function r( year, values ) { " + "var n = { count: 0}; "
                        + "for ( var i = 0; i < values.length; i++ ){"
                        + "n.count += values[i].count;" + "} " + "return n;"
                        + "}";

        final String f =
                "function f( year, value ){"
                        + "value.avg = value.sum / value.count;"
                        + "return value;" + "}";

        final MapReduceOutput out =
                coll.mapReduce(m, r, null, MapReduceCommand.OutputType.INLINE,
                        null);

        for (final DBObject obj : out.results()) {
            System.out.println(obj);
        }

    }
}