在Scala中修改Future [JsArray]

时间:2015-03-14 19:51:12

标签: mongodb scala playframework

我使用Play 2.0框架从MongoDB获取数据。

这可以通过以下代码完成:

def getTopicsInAppFormat = Action.async {
// let's do our query
val cursor: Cursor[TopicModel] = topicCollection.find(Json.obj()).cursor[TopicModel]

// gather all the JsObjects in a list
val futureTopicsList: Future[List[TopicModel]] = cursor.collect[List]()

// transform the list into a JsArray
val futurePersonsJsonArray: Future[JsArray] = futureTopicsList.map { topics =>
  Json.arr(topics)
}

// everything's ok! Let's reply with the array
futurePersonsJsonArray.map {
  topics =>
    Ok(topics(0))
}
}

但问题是我希望函数返回数据的替代表示。所以,我希望例如改变属性的数量等。实现这一目标的好方法是什么?我尝试在Ok()函数之前的最后一步修改数据(分别使用新格式创建一个新数组)。但是,我没有取得任何进展:/

编辑: 目前我正在尝试创建新的JSON对象,但是在从原始数据中获取数据时我被卡住了...... 我目前的代码如下:

futurePersonsJsonArray.map {
  topics =>

    /* Access a attribute */
    println(topics(0).\("content"))
    /* However: error: JsUndefined('content' is undefined on object */

    /* Could be used to set the new attributes */
    val myNewJson = Json.obj(
      "name" -> "JohnDoe",
      "age" -> "123",
      "created" -> new java.util.Date().getTime())

    Ok(/*topics(0)*/myNewJson)
}

2 个答案:

答案 0 :(得分:1)

您可能误解了topics的格式。您收到的消息告诉您content数组的第一个元素上没有topics属性。这是一个简化的例子:

val myObject = Json.obj("a" -> 1, "b" -> 2)
myObject \ "a" //JsNumber(1)
myObject \ "c" //JsUndefined('c' is undefined on object...)

这是有道理的,因为我们在尝试阅读不存在的属性时在Javascript中获得undefined。在Play Json库中,\始终返回JsValue,其中一个子类型为JsUndefined

您应该重新检查topics数组中对象的格式,然后重新评估如何访问其值。

答案 1 :(得分:0)

现在,我对问题的最终解决方案“在返回之前修改数据”看起来像这样:

futurePersonsJsonArray.map {
  topics =>

    def createNewFormat(uID: JsValue, name: JsValue, content: JsValue, lat: JsValue, lng: JsValue): JsObject = {
      return Json.obj(
        "id" -> uID,
        [...]
    }

    /* Access the needed attributes */
    val uIDs    = topics(0).\\("uID")
    val names   = topics(0).\\("name")
    val content = topics(0).\\("content")
    val gps     = topics(0).\\("gps")

    var dataArray = new JsArray()

    /* create new Array */
    for( i <- 0 to uIDs.length-1){
      dataArray = dataArray.append(createNewFormat(uIDs(i),names(i),content(i),gps(i)(0),gps(i)(1)))
    }

    /* put this into a new JSObject */
    var returnThis = Json.obj("data" -> dataArray)

    Ok(returnThis)
}

也许这确实可以帮助有类似问题的人:)