如何将 JSON 字符串转换为 BSONDocument [英] How to convert JSON String to a BSONDocument

查看:97
本文介绍了如何将 JSON 字符串转换为 BSONDocument的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下使用reactivemongo驱动程序的函数,实际上可以很好地写入数据库.

def writeDocument() = {val 文档 = BSONDocument(名字"->"斯蒂芬",姓氏"->《哥比伦》,年龄"->29)val future = collection.insert(document)未来.onComplete {case 失败(e) =>扔e案例成功(结果)=>{println("插入文档成功,result = " + result)}}}

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

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

更新 2:

包控制器//导入play.api.libs.json._//导入reactivemongo.bson._//导入play.api.libs.json.Json导入 scala.util.{成功,失败}导入reactivemongo.api._//导入 scala.concurrent.ExecutionContext.Implicits.global导入 play.modules.reactivemongo.json.collection._导入reactivemongo.play.json._对象蒙戈{//val collection = connect()定义集合:JSONCollection = {val 驱动程序 = 新的 MongoDriverval connection = driver.connection(List("localhost"))val db = connection("超人")db.collection[JSONCollection]("IncomingRequests")}//TODO: 使用任何 JSON 字符串执行此操作def writeDocument() = {val jsonString = """{|"guid": "alkshdlkasjd-ioqweuoiquew-123132",|"title": "Hello-2016",|年份":2016,|"action": "POST",|"开始": "2016-12-20",|"停止": "2016-12-30"}"""val 文档 = Json.parse(jsonString)val future = collection.insert(document)未来.onComplete {case 失败(e) =>扔e案例成功(结果)=>{println("插入文档成功,result = " + result)}}}}

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

[info] 将 9 个 Scala 源和 1 个 Java 源编译到/Users/superman/target/scala-2.11/classes...[错误]/Users/superman/app/controllers/Mongo.scala:89:找不到 Json 序列化程序作为 JsObject 类型的 play.api.libs.json.JsValue.尝试为这种类型实现隐式 OWrites 或 OFormat.[错误] 涉及默认参数的应用程序中发生错误.[错误] val future = collection.insert(document)[错误]^[错误] 发现一个错误[错误] (compile:compileIncremental) 编译失败[错误] 应用程序 -!@6oo00g47n - 内部服务器错误,对于(POST)[/validateJson] ->play.sbt.PlayExceptions$CompilationException: 编译错误 [没有 Json 序列化程序作为 JsObject 找到类型 play.api.libs.json.JsValue.尝试为这种类型实现隐式 OWrites 或 OFormat.涉及默认参数的应用程序中发生错误.]在 play.sbt.PlayExceptions$CompilationException$.apply(PlayExceptions.scala:27​​) ~[na:na]在 play.sbt.PlayExceptions$CompilationException$.apply(PlayExceptions.scala:27​​) ~[na:na]在 scala.Option.map(Option.scala:145) ~[scala-library-2.11.6.jar:na]在 play.sbt.run.PlayReload$$anonfun$taskFailureHandler$1.apply(PlayReload.scala:49) ~[na:na]在 play.sbt.run.PlayReload$$anonfun$taskFailureHandler$1.apply(PlayReload.scala:44) ~[na:na]在 scala.Option.map(Option.scala:145) ~[scala-library-2.11.6.jar:na]在 play.sbt.run.PlayReload$.taskFailureHandler(PlayReload.scala:44) ~[na:na]在 play.sbt.run.PlayReload$.compileFailure(PlayReload.scala:40) ~[na:na]在 play.sbt.run.PlayReload$$anonfun$compile$1.apply(PlayReload.scala:17) ~[na:na]在 play.sbt.run.PlayReload$$anonfun$compile$1.apply(PlayReload.scala:17) ~[na:na]

解决方案

首先,您可以使用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

你可以导入这两个

导入reactivemongo.play.json._导入 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._导入 play.api.libs.json._导入 play.modules.reactivemongo.json.collection.{JSONCollection, _}导入reactivemongo.api.MongoDriver导入reactivemongo.play.json._导入 play.api.libs.json.Reads._导入 scala.util.{失败,成功}对象蒙戈{定义集合:JSONCollection = {val 驱动程序 = 新的 MongoDriverval connection = driver.connection(List("localhost"))val db = connection("超人")db.collection[JSONCollection]("IncomingRequests")}def writeDocument() = {val jsonString = """{|"guid": "alkshdlkasjd-ioqweuoiquew-123132",|"title": "Hello-2016",|年份":2016,|"action": "POST",|"开始": "2016-12-20",|"停止": "2016-12-30"}"""val 文档 = Json.parse(jsonString).as[JsObject]val future = collection.insert(document)未来.onComplete {case 失败(e) =>扔e案例成功(结果)=>println("插入文档成功,result = " + result)}}}

重要的导入是

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

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

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

I have the following function that uses the reactivemongo driver and actually does a good job writing to the database.

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

But the limitation of that function is that the JSON is hardcoded into a BSONDocument. How can I change it so that I can pass any JSON String into the function?

Question in short: How do I convert a JSON String into a BSONDocument?

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

}

The problem now is that import reactivemongo.play.json._ is treated as an unused import (on my IntelliJ) and I still get the following error

[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]

解决方案

First, you could serialize your model classes as BSON using reactivemongo. Check docs to see how.

If you want to make a BSONDocument from String through play json you can use

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

Edit

I found more in the docs here:

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

you can import those two

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

Instead of using the default Collection implementation (which interacts with BSON structures + BSONReader/BSONWriter), we use a specialized implementation that works with JsObject + Reads/Writes.

So you create specialized collection like this (must be def, not val):

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

and from now on you can use it with play json, instead of BSON, so simply passing in Json.parse(jsonString) as a document to insert should work. You can see more examples in the link.

Edit 2 I got your code to compile:

package controllers

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

the important import is

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

and you need JsObject, not just any JsValue

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

这篇关于如何将 JSON 字符串转换为 BSONDocument的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆