blob: cb89cca2a92e3323595ce21bc544ccb29ac4414b [file] [log] [blame]
MongoDB supports [2d indexes|http://docs.mongodb.org/manual/core/2d/] that store points on a two-dimensional plane.
It is possible to use a MongoDB 2d index by mapping a list or map property using the @geoIndex@ mapping:
{code}
class Hotel {
String name
List location
static mapping = {
location geoIndex:'2d'
}
}
{code}
By default the index creation assumes latitude/longitude and thus is configured for a -180..180 range. If you are indexing something else you can customise this with @indexAttributes@
{code}
class Hotel {
String name
List location
static mapping = {
location geoIndex:'2d', indexAttributes:[min:-500, max:500]
}
}
{code}
You can then save Geo locations using a two dimensional list:
{code}
new Hotel(name:"Hilton", location:[50, 50]).save()
{code}
Alternatively you can use a map with keys representing latitude and longitude:
{code}
new Hotel(name:"Hilton", location:[lat: 40.739037d, long: 73.992964d]).save()
{code}
{note}
You must specify whether the number of a floating point or double by adding a 'd' or 'f' at the end of the number eg. 40.739037d. Groovy's default type for decimal numbers is @BigDecimal@ which is not supported by MongoDB.
{note}
Once you have your data indexed you can use Mongo specific dynamic finders to find hotels near a given a location:
{code}
def h = Hotel.findByLocationNear([50, 60])
assert h.name == 'Hilton'
{code}
You can also find a location within a box (bound queries). Boxes are defined by specifying the lower-left and upper-right corners:
{code}
def box = [[40.73083d, -73.99756d], [40.741404d, -73.988135d]]
def h = Hotel.findByLocationWithinBox(box)
{code}
You can also find a location within a circle. Circles are specified using a center and radius:
{code}
def center = [50, 50]
def radius = 10
def h = Hotel.findByLocationWithinCircle([center, radius])
{code}
If you plan on querying a location and some other value it is recommended to use a compound index:
{code}
class Hotel {
String name
List location
int stars
static mapping = {
compoundIndex location:"2d", stars:1
}
}
{code}
In the example above you an index is created for both the location and the number of stars a @Hotel@ has.