reactivemongo中的“$ centerSphere”查询

时间:2015-02-17 10:40:21

标签: mongodb scala geospatial latitude-longitude reactivemongo

我在这里找到click here

我想在reactivemongo中进行“2d”索引,然后想在reactivemongo中使用以下查询

db.collName.find({
    loc: {
    $geoWithin: {
        $centerSphere: [
            [lng, lat], radius / 6371
        ]
    }
    }
})

如何在reactivemongo中实现它?

任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

在reactivemongo中,此查询将如下所示:

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()
    }

我使用简单的案例类来测试这个:

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()
    }

}

并测试

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)
        }

    }

}