【问题标题】:How to convert JSON String to a BSONDocument如何将 JSON 字符串转换为 BSONDocument
【发布时间】:2016-01-15 19:39:32
【问题描述】:

我有以下函数,它使用了 reactivemongo 驱动程序,实际上在写入数据库方面做得很好。

def writeDocument() = {
    val document = BSONDocument(
      "firstName" -> "Stephane",
      "lastName" -> "Godbillon",
      "age" -> 29)

    val future = collection.insert(document)

    future.onComplete {
      case Failure(e) => throw e
      case Success(result) => {
        println("successfully inserted document with result = " + result)
      }
    }
  }

但该函数的局限性在于 JSON 被硬编码为 BSONDocument。如何更改它以便可以将任何 JSON 字符串传递给函数?

简而言之:如何将 JSON 字符串转换为 BSONDocument?

更新 2:

package controllers

//import play.api.libs.json._
//import reactivemongo.bson._
//import play.api.libs.json.Json

import scala.util.{Success, Failure}
import reactivemongo.api._
//import scala.concurrent.ExecutionContext.Implicits.global


import play.modules.reactivemongo.json.collection._
import reactivemongo.play.json._

object Mongo {

  //val collection = connect()

  def collection: JSONCollection = {
    val driver = new MongoDriver
    val connection = driver.connection(List("localhost"))
    val db = connection("superman")
    db.collection[JSONCollection]("IncomingRequests")
  }


  // TODO: Make this work with any JSON String
  def writeDocument() = {

    val jsonString = """{
                       | "guid": "alkshdlkasjd-ioqweuoiquew-123132",
                       | "title": "Hello-2016",
                       | "year": 2016,
                       | "action": "POST",
                       | "start": "2016-12-20",
                       | "stop": "2016-12-30"}"""


    val document = Json.parse(jsonString)
    val future = collection.insert(document)
    future.onComplete {
      case Failure(e) => throw e
      case Success(result) => {
        println("successfully inserted document with result = " + result)
      }
    }
  }

}

现在的问题是 import reactivemongo.play.json._ 被视为未使用的导入(在我的 IntelliJ 上),我仍然收到以下错误

[info] Compiling 9 Scala sources and 1 Java source to /Users/superman/target/scala-2.11/classes...
[error] /Users/superman/app/controllers/Mongo.scala:89: No Json serializer as JsObject found for type play.api.libs.json.JsValue. Try to implement an implicit OWrites or OFormat for this type.
[error] Error occurred in an application involving default arguments.
[error]     val future = collection.insert(document)
[error]                                   ^
[error] one error found
[error] (compile:compileIncremental) Compilation failed
[error] application - 

! @6oo00g47n - Internal server error, for (POST) [/validateJson] ->

play.sbt.PlayExceptions$CompilationException: Compilation error[No Json serializer as JsObject found for type play.api.libs.json.JsValue. Try to implement an implicit OWrites or OFormat for this type.
Error occurred in an application involving default arguments.]
        at play.sbt.PlayExceptions$CompilationException$.apply(PlayExceptions.scala:27) ~[na:na]
        at play.sbt.PlayExceptions$CompilationException$.apply(PlayExceptions.scala:27) ~[na:na]
        at scala.Option.map(Option.scala:145) ~[scala-library-2.11.6.jar:na]
        at play.sbt.run.PlayReload$$anonfun$taskFailureHandler$1.apply(PlayReload.scala:49) ~[na:na]
        at play.sbt.run.PlayReload$$anonfun$taskFailureHandler$1.apply(PlayReload.scala:44) ~[na:na]
        at scala.Option.map(Option.scala:145) ~[scala-library-2.11.6.jar:na]
        at play.sbt.run.PlayReload$.taskFailureHandler(PlayReload.scala:44) ~[na:na]
        at play.sbt.run.PlayReload$.compileFailure(PlayReload.scala:40) ~[na:na]
        at play.sbt.run.PlayReload$$anonfun$compile$1.apply(PlayReload.scala:17) ~[na:na]
        at play.sbt.run.PlayReload$$anonfun$compile$1.apply(PlayReload.scala:17) ~[na:na]

【问题讨论】:

  • 你在使用 reactivemongo 插件吗?
  • 我同时使用 reactivemongo 和 play-reactive 模块

标签: json scala playframework reactivemongo play-reactivemongo


【解决方案1】:

首先,您可以使用 reactivemongo 将模型类序列化为 BSON。查看文档以了解如何操作。

如果你想通过播放 json 从String 制作一个BSONDocument,你可以使用

val playJson: JsValue = Json.parse(jsonString)
val bson: BSONDocument = play.modules.reactivemongo.json.BSONFormats.reads(playJson).get

编辑

我在此处的文档中找到了更多信息:

http://reactivemongo.org/releases/0.11/documentation/tutorial/play2.html

你可以导入这两个

import reactivemongo.play.json._
import play.modules.reactivemongo.json.collection._

而不是使用默认的 Collection 实现(与 BSON 结构 + BSONReader/BSONWriter),我们使用专门的 与 JsObject + Reads/Writes 一起使用的实现。

所以你创建这样的专门集合(必须是def,而不是val):

def collection: JSONCollection = db.collection[JSONCollection]("persons")

从现在开始,您可以将它与 play json 一起使用,而不是 BSON,因此只需将 Json.parse(jsonString) 作为要插入的文档传入就可以了。您可以在链接中查看更多示例。

编辑 2 我得到了你的代码来编译:

包控制器

import play.api.libs.concurrent.Execution.Implicits._
import play.api.libs.json._
import play.modules.reactivemongo.json.collection.{JSONCollection, _}
import reactivemongo.api.MongoDriver
import reactivemongo.play.json._
import play.api.libs.json.Reads._

import scala.util.{Failure, Success}


object Mongo {

  def collection: JSONCollection = {
    val driver = new MongoDriver
    val connection = driver.connection(List("localhost"))
    val db = connection("superman")
    db.collection[JSONCollection]("IncomingRequests")
  }

  def writeDocument() = {

   val jsonString = """{
                       | "guid": "alkshdlkasjd-ioqweuoiquew-123132",
                       | "title": "Hello-2016",
                       | "year": 2016,
                       | "action": "POST",
                       | "start": "2016-12-20",
                       | "stop": "2016-12-30"}"""


    val document = Json.parse(jsonString).as[JsObject]
    val future = collection.insert(document)
    future.onComplete {
      case Failure(e) => throw e
      case Success(result) =>
        println("successfully inserted document with result = " + result)
    }
  }
}

重要的导入是

import play.api.libs.json.Reads._

你需要JsObject,而不仅仅是任何JsValue

val document = Json.parse(jsonString).as[JsObject]

【讨论】:

  • 我已经导入了 play.modules.reactivemongo.json.BSONFormats._。但是它仍然抱怨reads 无法解决。
  • 也许尝试不使用._ 并使用限定名。我不确定,我只是使用了文档:reactivemongo.org/releases/0.11/play-api/…,可以在 reactivemongo 网站的“Play module API”下找到
  • 我认为这在 0.11.9 中已被弃用,但您的解决方案看起来最简单。
  • 太棒了!那行得通:D,顺便说一句,即使没有import play.api.libs.json.Reads._,我的作品也能工作——谢谢:)
  • 这个例子给了我:“引起:java.lang.NoSuchMethodError: play.api.libs.json.JsLookup$.$bslash$extension(Lplay/api/libs/json/JsLookupResult;Ljava /lang/String;)Lplay/api/libs/json/JsLookupResult;".我尝试在网上搜索它,但没有一个解决方案对我有意义。我的猜测是我缺少一个依赖项,你会碰巧知道哪个吗?
【解决方案2】:

ReactiveMongo release note 备注:

在使用对Play JSON的支持时,如果出现上一个错误,它 有必要确保使用 import reactivemongo.play.json._,以 导入默认 BSON/JSON 转换。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-21
    • 1970-01-01
    • 2011-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多