MongoDB Java Driver notes

A few notes on using the MongoDB Java Driver API:

Getting a connection:

MongoClient client = new MongoClient("localhost", 27017);
DB db = client.getDB("test");

Get a collection from connected db:

DBCollection collection = db.getCollection("example");

 

Find all docs in collection and iterate through results:

DBCursor c = collection.find();
try {
   while(c.hasNext()) {
       System.out.println(c.next());
   }
} finally {
   c.close();
}

 

Simple findOne query, matching a doc with properyname = value:

DBObject result = collection.findOne(new BasicDBObject("propertyname", "value"));

 

Find all, sort on property ‘example’ ascending (1=asc, -1=desc), and limit to 10 results:

DBCursor c = collection.find()
    .sort(new BasicDBObject("example", 1))
    .limit(10);

 

Serialize results of a cursor to JSON (tip from here):

JSON json = new JSON();
String jsonString = json.serialize(c);

MongoDB install on a Mac

By default MongoDB uses /data/db as it’s location for databases. You need to create this dir and then chown it to the user running mongod. For example:

sudo chown username /data/db

More info here.

Using Hibernate OGM to persist objects to MongoDB (deploying to Wildfly 8.2)

For storing data when you’re less concerned about relationships between your data but more interested in entities (documents) and their attributes, a document-based datastore like MongoDB makes a lot of sense. MongoDB’s Java Driver API though is rather clunky in it’s usage pattern.

So I started looking for alternatives. The MongoDB Java ecosystem page has a good collection of some libraries to consider. Initially I took a quick look at MongoJack, which looked like an interesting approach to map between Java POJOs to json data representations (using the Jackson api). I remember reading a while back at Morphia, and was interested what a JPA based approach to interacting with MongoDB would look like. Somewhere I stumbled across the Hibernate OGA project – being a fan of ORM approaches popularized by Hibernate, I wanted to take a look.

The current Hibernate OGM docs (4.1) are here.

For deploying on JBoss/WildFly, OGM is supplied as modules in a zip that you can unzip directly into the modules dir on the server. See here more more details.

Deploying to OpenShift, as for most cartridges, your configuration values are defined in environment variables. Instead of hardcoding the properties and values in your persistence.xml, you can have them passed to your server at startup by adding them to a JAVA_OPTS_EXT file like this (do this one time to create the file):

echo "-Dhibernate.ogm.datastore.host=$OPENSHIFT_MONGODB_DB_HOST \
    -Dhibernate.ogm.datastore.port=$OPENSHIFT_MONGODB_DB_PORT \
    -Dhibernate.ogm.datastore.username=$OPENSHIFT_MONGODB_DB_USERNAME \
    -Dhibernate.ogm.datastore.password=$OPENSHIFT_MONGODB_DB_PASSWORD" \
    > .env/user_vars/JAVA_OPTS_EXT

Mapping your Entities and Id properties

At some point support for the ObjectId MongoDB id type was added. In the current docs don’t use the uuid id generator, use the ‘objectid’ type described here instead:

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Type(type = "objectid")

 

JPA Persistence.xml

Here’s what my persistence.xml looks like:
[code language=”xml”]

org.hibernate.ogm.jpa.HibernateOgmPersistence if entities not in same jar, list here

[/code]

MongoDB usage notes

MongoDB Shell commands:

#list dbs on server:
show dbs
#show collections in current db
show collections
#switch to db
use databasename;

#find everything and print as json
db.collectionname.find().forEach(printjson);

#'like' query:
db.collectionname.find(fieldname:/pattern/).forEach(printjson);

#count results:
db.collectionname.find().count();

#return only requested properties (similar to 'select x, y, z from table a')
db.collectionname.find({}, {fieldname1:1, fieldname2:1}).forEach(printjson)

#select min x by sorting in asc order and picking first result
db.collectionname.find().sort({x: 1}).limit(1).forEach(printjson)

#select max x by sorting in desc order and picking first result
db.collectionname.find().sort({x: -1}).limit(1).forEach(printjson)

#add an index for property x
db.collectionname.ensureIndex({x: 1})

Stats webapp: http://localhost:28017/