In reactivemongo this query would look like this:
def findNear(lng: Double, lat: Double, radius: Double)(implicit fomrat: Format[T], ec: ExecutionContext): Enumerator[T] = {
collection().
find(Json.obj("loc" -> Json.obj("$geoWithin" -> Json.obj("$centerSphere" -> Json.arr(Json.arr(lng, lat), JsNumber(radius / 6371)))))).
cursor[T].
enumerate()
}
I've played with simple case class, to test this:
case class Company(name: String, loc: Point)
case class Point(lon: Double, lat: Double)
object Company extends MongoCollection[Company] {
implicit val pointFormat: Format[Point] = Json.format[Point]
implicit val companyFormat: Format[Company] = Json.format[Company]
val collectionName = "company"
def findNear(lng: Double, lat: Double, radius: Double)(implicit ec: ExecutionContext): Enumerator[Company] = {
collection().
find(Json.obj("loc" -> Json.obj("$geoWithin" -> Json.obj("$centerSphere" -> Json.arr(Json.arr(lng, lat), JsNumber(radius / 6371)))))).
cursor[Company].
enumerate()
}
}
and test
object CompanySpec extends Specification with NoTimeConversions {
sequential
"geo spatial" should {
val A = Company("A", Point(0, 0))
val B = Company("B", Point(0, 1))
val C = Company("C", Point(1, 1))
val D = Company("D", Point(1, 0))
Company.saveAll(List(A, B, C, D)).await()
"return A " in {
Company.findNear(0, 0, 1).collect().await() shouldEqual List(A)
}
"return A, B, C" in {
Company.findNear(0, 0, 120).collect().await() shouldEqual List(A, B, D)
}
"return D" in {
Company.findNear(0, 0, 240).collect().await() shouldEqual List(A, B, C, D)
}
}
}