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

 

About Author

Author Image
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

Request for Proposal

Name is required

Comment is required

Sending message..