Вернуть ReactiveMongo JSON в Play Framework

Каков самый быстрый способ вернуть текст JSON из BSONArray?

Я возвращаю очень большой документ JSON. Можно ли пропустить обработку Play JsValue

Сейчас возвращаюсь вот так:

 val result:BSONArray = ....
 Ok(Json.toJson(result))

Я думаю, что быстрее было бы что-то вроде:

 Ok(result.toTextJSON).as(MimeTypes.JSON)

Обновите здесь мой полный код:

val command = Json.parse( s""" {
  "aggregate": "$collection",
  "pipeline": [
  { "$$match": { "$$and" : [
      { "${RootAttrs.TIME}" : { "$$gt": $startSecTime }},
      { "${RootAttrs.TIME}" : { "$$lt": $endSecTime }},
      { "${RootAttrs.COMMAND}" : { "$$eq": ${toCmd(Command.GPS_COORDINATES)} }}
    ]
  }},
  { "$$sort": { "${RootAttrs.TIME}" : 1 }},
  { "$$limit": $MAX_GPS_ALL_DATA },
  { "$$project" : { "_id":0, "${RootAttrs.TIME}":1, "${RootAttrs.COMMAND}":1, "${RootAttrs.VALUE}":1, "${RootAttrs.IGNITION}":1, "${RootAttrs.SIM_NUMBER}":1 } }
]}""")

db.command(RawCommand(BSONDocumentFormat.reads(command).get)).map { out =>
  out.get("result").map {
    case result: BSONArray =>
      Logger.debug("Loaded all GPS history data size: " + result.length)
      Ok(Json.toJson(result)) // <- I need just return JSON, parsing to JsValue can take some time

    case _ =>
      Logger.error("Result GPS history data not array")
      BadRequest

  }.getOrElse(BadRequest)
}

person Michał Jurczuk    schedule 21.07.2016    source источник
comment
Не могли бы вы добавить сюда более подробный пример кода?   -  person marcospereira    schedule 21.07.2016


Ответы (1)


Вы можете пропустить этап создания промежуточного JsValue, если хотите создать свой собственный Writeable, и вывести строку вручную.

Вот простой пример, который можно настроить в соответствии с вашими потребностями.

val result: BSONArray = BSONArray("one", "two", "three")

def convertBsonArrayToString(jsval: BSONArray): Array[Byte] = {
  // this method assumes I have a BSONArray of Strings (which you may not)
  var strs: Stream[String] = jsval.stream.map(_.get match { case s: BSONString => s.value })
  var json: String = strs.mkString("[\"", "\",\"", "\"]")
  json.getBytes()
}

implicit def writeableOf_BSONArray: Writeable[BSONArray] = {
  Writeable(convertBsonArrayToString ,Some("application/json"))
}

def doStuff = action {
  Results.Ok(result)
}

Ответ выше: ["один", "два", "три"].

Если вы имеете дело с большими объемами данных - вам также может быть лучше использовать Enumerator и передавать ответ в потоковом режиме.

см .: https://www.playframework.com/documentation/2.5.x/ScalaStream

person Bruce Lowe    schedule 23.07.2016
comment
Мне это кажется изобретением велосипеда. - person cchantep; 25.07.2016