The mongo module adds MongoDB support for the Play! framework.
In the /conf/application.conf file, enable the Mongo module by adding this line:
# The mongo module module.mongo=${play.path}/modules/mongo# mongodb connection details mongo.host=localhost mongo.port=27017 mongo.database=playmongo.username=test mongo.password=test123
Creating models to be stored in your Mongo database is very similar to the method of creating
models in the Play! framework for storage in an SQL database. Provide them with an annotation
and have them inherit from a base class, as follows:
@MongoEntity("collectionName") public class Car extends MongoModel {public String name; public String colour; public int topSpeed;}
If collectionName is not supplied as a value to the annotation, the collection name will be the
same as the class name.
After defining your models, you can use them in the same way as you would a standard SQL based
model in Play! framework. The examples below describe how you might use your Mongo based models in a controller.
Saving is simple.
Car myCar = new Car("Toyota", "white", 150);
myCar.save();There are a number of ways to find your models.
//get all cars List<Car> allCars = Car.find().fetch();//get any five cars List<Car> fiveCars = Car.find().fetch(5);//get any two cars with offset of 3 List<Car> offsetCars = Car.find().from(3).fetch(2);//get the third page of 20 cars List<Car> pageOfCars = Car.find().fetch(3,20);//get only one car Car c = Car.find().first();
You can pass query strings when using the find method like so:
List<Car> toyotas = Car.find("byName", "Toyota").fetch();List<Car> whiteToyotas = Car.find("byNameAndColour", "Toyota", "white").fetch();
Currently the Mongo module only supports the ‘And’ query operator.
Ordering your results is very simple, allowing the use of a query very similar to the find.
List<Car> ascendingNameCars = Car.find().order("byName").fetch();// to perform a descending order, prefix the field with '-' List<Car> descendingNameCars = Car.find().order("by-Name").fetch();
Counting your models is again, simple.
long count = Car.count()// alternatively, pass a query string long toyotaCount = Car.count("byName", "Toyota");
Deleting can be done at the model level, or against the entire collection.
Car c = Car.find().first(); c.delete();// or to delete using a query string Car.delete("byName","Toyota");// or just delete everything Car.deleteAll();
Mongo module does not yet support any relationships between models. If you need to model complex relationships then Mongo might not be the correct solution for you.
However, Mongo module does support inner models or POJOs within your MongoModel classes. It even supports arrays of both primitive types or POJOs. Unfortunately, only collections of primitive types are currently supported. This is due to runtime erasure of generic types.
//As of version 1.1 you no longer require special annotations for inner POJOs. public class Driver { public String name; }// and declare this object a member of your model class @MongoEntity("cars") public class Car extends MongoModel {public String name; public String colour; public int topSpeed;// the mongo object public Driver driver;}
Now when we save our MongoModel to a mongo database, the MongoObject is stored as an inner JSON document. This gives us the ability to access its properties via its parent model in view templates:
<p> Driver Name: ${car.driver.name} </p>Or use properties of the inner model as part of our query strings:
Car andrewCar = Car.find(byDriver.name,"Andrew").first();Models are automatically saved with a Mongo ObjectId to the specified collection. Both the ObjectId and collection name can be accessed from the model.
Car myCar = new Car("Toyota", "white", 150); myCar.save();ObjectId id = myCar.get_id(); String colName = myCar.getCollectionName();
It is possible to create indexes against your models.
// index the name field of Car Car.index("onName");// create a descending index by prepending the '-' character Car.index("on-Name");// create a composite index by combining field names Car.index("onNameAndColour");// remove an index Car.dropIndex("onName);// remove all indexes (except the mandatory mongo index on _id) Car.dropIndexes();// get the names of all the existing indexes String [] indexNames = Car.getIndexes();
Due to the schemaless nature of mongo, it is possible to create an index on a field which does not exist because a document containing that field may be inserted in the future. Ensure you spell your field names correctly.
It is possible to run your mongo database in a secure mode, ensuring that a user must authenticate prior to performing operations on secure data. More information on setting up a secure mongo instance can be found on the Mongo website under Security and Authentication.
Assuming you have setup your database correctly, you can leverage the authentication functionality of the mongo module as follows:
# ensure you set the necessary configuration parameters to match authentication details on your database
mongo.username=test
mongo.password=test123Now you can perform the following operations in your controllers.
//add a user - with read only access MongoDB.addUser("username","password", true);// or write access MongoDB.addUser("username2","password2", false);// authenticate as a user boolean success = MongoDB.authenticate("username","password");// remove a user MongoDB.removeUser("username");
Please note that readOnly restrictions will only apply on mongo versions 1.3.2+
Included in the module distribution is a play-mongo-test directory. This is a play framework application that runs the code shown in the documentation above. The best to run this is to create a new play framework application and to copy the contents of the play-mongo-test directory there. Be sure to update the path to the mongo module as shown above.
The next step for play-mongo will to be update the module to use the new JPA features provided in version 1.1 of the framework.