The MongoDB Grails plugin is primarily exposed to Grails applications as a Spring bean called ‘mongo’.
Grails classes can then easily make use of it throughout their code by simply adding a ‘mongo’
property to their classes which support dependency injection (domain/controllers/services), eg:
class UserController{ def mongo }
At startup the MongoDB plugin will look for a ‘mongo’ configuration property in your
Config.groovy file which defines your MongoDB databases and related configuration
properties.
#Config.groovy mongo{ databases{ server1{ host = "localhost" port = 1234 // if omited, will use the default MongoDB port } server2{ host = "192.168.1.2" } } shortcuts{ users = "server1/app/users" comments = "server2/app/comments" } }
The above example registers two different database hosts which can then be accessed using the mongo
bean: mongo.server1.<dbname>.<collection>
. ‘dbname’ and ‘collection’ will
return the corrisponding Java MongoDB driver equivalents (DB, DBCollection).
Shortcuts can also be defined to shorten the syntax required to access a collection by registering a
root-level mongo property directly with a collection. For example, in the above
example we mapped the ‘users’ shortcut to “server1/app/users”, which lets us use mongo.users
instead of mongo.server1.app.users
.
Shortcuts have the added benefit of making it easier to change your server topology without having to
change your code; if you were to move your users collection to a different server, you would just update
your alias.
Shortcuts will also be used in the future to reference server-pools.
The MongoDbWrapper makes it easy to save and restore your Grails domain objects
to a collection by using mappers which convert your domain objects to BasicDBObjects,
and vice-versa.
To register your Domain class with a mapper you need to add two static helper fields
to your class:
class User{ String firstName String lastName static mongoTypeName = "user" static mongoFields = ['fn':firstName','ln':'lastName'] }
When your objects are converted to documents a property ‘_t’ is added to help identify the type.
This type identifier is specified with mongoTypeName
. You then specify which fields
should be saved, and their respective keys.
Domain objects can then be coverted to docs by calling the MOP added method “toMongoDoc()”.
def user = new User( firstName:"mark", lastName:"priatel" ) def userDoc = user.toMongoDoc()
You can also convert documents retured from queries back into their Domain equivilants
using the toObject()
method added to BasicDBObject and BasicDBList (via MOP):
mongo.users.find().each{ doc -> def userDomainObject = doc.toObject() }
The mapper will also process mapped properties and Lists:
class Address{ String city String country static mongoTypeName = "address" static mongoFields = [ 'ci':'city' , 'co' : 'country' ] } class User{ String firstName String lastName Address address static mongoTypeName = "user" static mongoFields = ['fn':firstName','ln':'lastName','adrs':'address'] } def adrs = new Address( city:'ottawa' , country:'canada' ) def user = new User( firstName:'mark', lastName:'priatel',address:adrs) mongo.users.save( user.toMongoDoc() ) (bson) { "_id" : ObjectId("4b952284d8e992502c9629e3"), "_t" : "u", "fn" : "mark", "ln" : "priatel", "adrs" : { "_t" : "a", "ci" : "ottawa", "co" : "canada" } }
Of course, you can still save your domain objects using GORM.
def user = new User( firstname:"mark" ) user.save() mongo.users.save( user.toMongoDoc() )
The mongo bean exposes a special root-level property ‘doc’ which can be used to create
BasicDBObjectS (which are used by the Java driver to represent MongoDB documents) using a
Groovy builder syntax:
def userData = mongo.doc{ firstName("mark") lastName("priatel") company("iolog") address{ city("ottawa") country("canada") } } mongo.user.save(userData) println userData._id
-