Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mongodb 如何在ReactiveMongo模型中表示GeoJSON点?_Mongodb_Scala_Playframework_Playframework 2.2_Reactivemongo - Fatal编程技术网

Mongodb 如何在ReactiveMongo模型中表示GeoJSON点?

Mongodb 如何在ReactiveMongo模型中表示GeoJSON点?,mongodb,scala,playframework,playframework-2.2,reactivemongo,Mongodb,Scala,Playframework,Playframework 2.2,Reactivemongo,为了在MongoDB中进行地理空间查询,具有位置(具有2d或2dsphere地理空间索引)的文档应如下所示: { _id: …, loc: { type: "Point", coordinates: [ <longitude>, <latitude> ] } } package controllers import play.api._ import play.api.mvc._ import play.api.

为了在MongoDB中进行地理空间查询,具有位置(具有
2d
2dsphere
地理空间索引)的文档应如下所示:

{
    _id: …,
    loc: {
        type: "Point",
        coordinates: [ <longitude>, <latitude> ]
    }
}
package controllers

import play.api._
import play.api.mvc._
import play.api.libs.json._
import scala.concurrent.Future

// Reactive Mongo imports
import reactivemongo.api._
import scala.concurrent.ExecutionContext.Implicits.global

// Reactive Mongo plugin
import play.modules.reactivemongo.MongoController
import play.modules.reactivemongo.json.collection.JSONCollection

object Application extends Controller with MongoController {
    def collection: JSONCollection = db.collection[JSONCollection]("test")

    import play.api.data.Form
    import models._
    import models.JsonFormats._

    def createCC = Action.async {
        val user = User("John", "Smith", Point(-0.0015, 51.0015))
        val futureResult = collection.insert(user)
        futureResult.map(_ => Ok("Done!"))
    }
}
网站API处理的JSON表示应该类似于:

{
    _id: …
    loc: [ <longitude>, <latitude> ]
}
{
    "_id": ObjectId("52ac76dd1454bbf6d96ad1f1"),
    "loc": {
        "lon": -0.0015,
        "lat": 51.0015 
    }
}
我尝试使用PointWriter和PointReader。这是我的型号。scala:

package models

import reactivemongo.bson._
import play.modules.reactivemongo.json.BSONFormats._

case class User(
    // _id: Option[BSONObjectID],
    firstName: String,
    lastName: String,
    loc: Point)

case class Point(lon: Double, lat: Double)

object Point {
    implicit object PointWriter extends BSONDocumentWriter[Point] {
        def write(point: Point): BSONDocument = BSONDocument(
            "type" -> "Point",
            "coordinates" -> Seq(point.lat, point.lon)
        )
    }

    implicit object PointReader extends BSONReader[BSONDocument, Point] {
        def read(doc: BSONDocument): Point = Point(88, 88)
    }
}

object JsonFormats {
    import play.api.libs.json.Json
    import play.api.data._
    import play.api.data.Forms._

    import play.api.libs.json._
    import play.api.libs.functional.syntax._

    implicit val pointFormat = Json.format[Point]
}
当我调用controller action
createCC
时,我希望在新创建的文档中有一个格式正确的Point对象,但我实际得到的是:

{
    _id: …
    loc: [ <longitude>, <latitude> ]
}
{
    "_id": ObjectId("52ac76dd1454bbf6d96ad1f1"),
    "loc": {
        "lon": -0.0015,
        "lat": 51.0015 
    }
}
因此,我尝试使用
PointWriter
PointReader
来告诉ReactiveMongo如何将这样一个
Point
对象写入数据库,但毫无效果

有人能帮我理解我要做什么吗

(我来自PHP背景,试图了解Scala…)

更新: 多亏了tmbo的回答,我找到了这位作家:

val pointWrites = Writes[Point]( p =>
    Json.obj(
        "type" -> JsString("Point"),
        "coordinates" -> Json.arr(JsNumber(p.lon), JsNumber(p.lat))
    )
)

您面临的问题与
JSONCollection
BSONCollection
之间的混淆有关

BSONCollection
reactivemongo使用的默认集合。这个实现需要一个
BSONDocumentWriter
和一个
BSONReader
的实现,这样case类才能(反)序列化

另一方面,
JSONCollection
播放响应模块使用的默认采集实现。由于在
db.collection[JSONCollection](“test”)中将集合定义为
JSONCollection
,因此需要提供隐式json格式

您提供的json格式是

implicit val pointFormat=Json.format[Point]
这会将对象序列化为以下格式

{
    "lon": -0.0015,
    "lat": 51.0015 
}
如果要将
序列化为数组,则需要替换上述隐式
点格式

import play.api.libs.json_
导入play.api.libs.json.Reads_
案例等级点(lng:Double,lat:Double)
目标点{
val pointWrites=Writes[Point](p=>Json.toJson(List(p.lng,p.lat)))
val pointReads=minLength[List[Double]](2).map(l=>Point(l(0),l(1)))
隐式val pointFormat=格式(点读取、点写入)
}
实际上,您不需要
BSONReader
BSONDocumentWriter

编辑: 下面是一个reads,它还验证文档的
type
属性:


嘿@tmbo,谢谢你的回答!虽然这不能提供我所需要的格式,但我的问题的核心是,为什么我的读者/作者被忽视了。这将对我有很大帮助,我将在几个小时后发布我的结果。我想将其调整为(反)序列化为不同的格式应该不难。但是如果你需要任何帮助,请告诉我。多亏了你的回答,我很容易就明白了作者应该是什么样子。这就是我的想法,它是有效的:(见我上面问题中的更新。)但我正在与读者抗争,这让我觉得我可能必须回到几个步骤,学习更多有关Scala和Play的基本知识。我添加了一个更适合您的结构的替代方案