0

У меня есть следующая функция, которая использует драйвер reactivemongo и на самом деле хорошо записывает работу в базу данных.Как преобразовать строку JSON в BSONDocument

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?

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

} 

Сейчас проблема заключается в том, что 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] 
+0

вы используете reactivemongo плагин? – Barry

+0

Я использую как реактивный, так и игровой реактивный модуль – summerNight

ответ

3

Во-первых, может сериализовать ваши классы моделей в качестве BSON с использованием реактивной технологии. Проверьте документы, чтобы узнать, как это сделать.

Если вы хотите сделать BSONDocument из String через игру JSON можно использовать

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._ 

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.

Таким образом, вы создать специальную коллекцию, как это (должно быть def, не val):

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

и теперь вы можете использовать его с игровыми JSON, вместо BSON, так просто прохождение в Json.parse(jsonString) в качестве документа для вставки должно работать. Вы можете увидеть больше примеров в ссылке.

Edit 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] 
+0

У меня есть play.modules.reactivemongo.json.BSONFormats._ импортировано. Однако он все еще жалуется, что 'reads' не может быть разрешен. – summerNight

+0

Возможно, попробуйте без '._' и используйте квалифицированное имя. Я не уверен, я просто пошел с документами: http://reactivemongo.org/releases/0.11/play-api/index.html#play.modules.reactivemongo.json.BSONFormats$, которые можно найти на сайте reactivemongo в разделе «API модуля воспроизведения» –

+0

Я думаю, что это было устарело в 0.11.9, но ваше решение выглядит проще всего. – summerNight

0

В ReactiveMongo release note примечания:

When using the support for Play JSON, if the previous error occurs, it necessary to make sure import reactivemongo.play.json._ is used, to import default BSON/JSON conversions.

+0

См. Обновление 2 – summerNight