Complex Custom queries in Mongodb Grails using GMongo
Posted By : Akash Sharma | 17-Apr-2014
Recently I had a requirement in my grails project (grails with mongodb ) where I had to create some complex queries via my application.
Following were the example where dynamic finders or create criteria does not work :
(1) Storing a map in a domain and finding objects on the basis of a key-value pair
(2) Storing a list in a domain and finding objects with matching field in the list
There can be more complex nested problems with mongodb like storing map in a list which reside in a domain and then finding the values from database.
One solution for this was to use Native low level java quiries which is automatically supported by grails mongodb plugin.
Second solution is using GMongo.
I used second approach.
Lets start with an example.
I created a domain as Location and created its corresponding DAO methods in a Service.
class Location { HashMap<String,String> baseAddr ArrayList<String> mobileNumbers static mapWith="mongo" }
DataSource.groovy
grails { mongo { host = "localhost" port = 27017 username = "myusername" password = "mypassword" databaseName = "myDB" } }
Data stored in DB looks like:
db.location.findOne() { "_id" : NumberLong(1), "baseAddr" : { "country" : "india", "city" : "delhi" }, "mobileNumbers" : [ "999-222-1111", "999-222-3333" ], "version" : 0 }
Service class that has methods for finding key-value pair in map and finding entity in a list
MongoDaoService.groovy
import grails.transaction.Transactional import javax.annotation.PostConstruct import com.gmongo.GMongo import com.mongodb.DB @Transactional class MongoDaoService { def grailsApplication private String host,databaseName,username,password private int port /** * This post construct method initializes DB configuration parameters * as a member variable after initialization of grailsApplication */ @PostConstruct private void init() { host=grailsApplication.config.grails.mongo.host databaseName=grailsApplication.config.grails.mongo.databaseName username=grailsApplication.config.grails.mongo.username password=grailsApplication.config.grails.mongo.password port=grailsApplication.config.grails.mongo.port } /** * Returns list of all Location objects having baseAddr.city == city * @param city * @return */ public ArrayList<Location> findAllLocationByCityInBaseAddr(String city){ GMongo mongo = new GMongo(host, port) DB db = mongo.getDB(databaseName) boolean auth = db.authenticate(username, password.toCharArray()) ArrayList locationList=db.location.find(["baseAddr.city": city]).toArray() return locationList.collect{ it as Location } } /** * Returns list of Location objects whose list of mobileNumbers contain mobileNumber * @param mobileNumber * @return */ public ArrayList<Location> findAllLocationByMobileNumber(String mobileNumber){ GMongo mongo = new GMongo(host, port) DB db = mongo.getDB(databaseName) boolean auth = db.authenticate(username, password.toCharArray()) ArrayList locationList=db.location.find(["mobileNumbers": mobileNumber]).toArray() return locationList.collect{ it as Location } } }
Thanks
Akash Sharma
Cookies are important to the proper functioning of a site. To improve your experience, we use cookies to remember log-in details and provide secure log-in, collect statistics to optimize site functionality, and deliver content tailored to your interests. Click Agree and Proceed to accept cookies and go directly to the site or click on View Cookie Settings to see detailed descriptions of the types of cookies and choose whether to accept certain cookies while on the site.
About Author
Akash Sharma
Akash is a bright Groovy and Grails developer and have worked on development of various SaaS applications using Grails technologies. Akash loves playing Cricket and Tennis