首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >对ReactiveMongo错误的误解

对ReactiveMongo错误的误解
EN

Stack Overflow用户
提问于 2016-02-05 15:43:42
回答 1查看 756关注 0票数 0

我定义了以下类,我想对其建模:

代码语言:javascript
复制
case class Record(
                     recordKey: String,
                     channels: Map[String, Channel],
                     )

  object Record {
    implicit val RecordFormat = Json.format[Record]
  }

现在,我想从像这样的反应性mongo (在另一个类中)中获取这种类型的对象:

代码语言:javascript
复制
import scala.concurrent.duration._
import scala.concurrent.{Future, Await}
import scala.concurrent.ExecutionContext.Implicits.global
import reactivemongo.api._
import reactivemongo.api.collections.bson.BSONCollection
import reactivemongo.bson.BSONDocument

object Test {
  val collection = connect()
  val timeout = 10.seconds
  def connect() : BSONCollection = {
    val config = ConfigFactory.load()
    val driver = new MongoDriver
    val connection = driver.connection(List(config.getString("mongodb.uri")))
    val db = connection("/toto")
    db.collection("foo")
  }

  def findRecord(recordKey : String) : Record = {
    return Test.collection
      .find(BSONDocument("recordKey"->recordKey))
      .one[Record]
  }

但是这段代码没有编译:

代码语言:javascript
复制
 could not find implicit value for parameter reader: reactivemongo.bson.BSONDocumentReader[Record]

有人能解释一下如何解决这个问题吗?

我还测试:

代码语言:javascript
复制
def findRecord(recordKey : String) : Record = {
    val futureRecord : Future[Option[Record]] =
      Test.collection
        .find(BSONDocument("recordKey"->recordKey))
        .one[Record]
    return Await.result(futureRecord, 10.seconds).getOrElse(null)
  }

我还添加了我的build.sbt

代码语言:javascript
复制
libraryDependencies ++= Seq(
  "org.apache.spark" % "spark-streaming_2.10" % "1.5.2",
  "org.apache.spark" % "spark-streaming-kafka_2.10" % "1.5.2",
  "org.slf4j" % "slf4j-api" % "1.7.13",
  "org.slf4j" % "slf4j-simple" % "1.7.13",
  "com.amazonaws" % "aws-java-sdk" % "1.10.12",
  "com.typesafe.play" % "play-json_2.10" % "2.4.6",
  "com.typesafe" % "config" % "1.3.0",
  "org.scalaj" %% "scalaj-http" % "2.2.1",
  "com.typesafe.akka" % "akka-actor_2.10" % "2.3.14",
  "org.reactivemongo" %% "reactivemongo" % "0.11.9",
  "com.github.nscala-time" %% "nscala-time" % "2.6.0"
)

注意,这不是一个Play App

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-02-05 16:34:06

您需要为case类BSONDocumentReader定义一个Record。下面是指向文档的链接。与播放JSON阅读器和作家非常相似,Reactive需要了解如何在域对象和BSONDocument之间来回转换。与玩JSON类似,您也可以用更手动的方式(编写BSONDocumentReader实例和BSONDocumentWriter实例)写出这些内容,并定制每个细节并应用转换等等。与您在上面使用的JSON的format类似,ReactiveMongo确实提供了一些有用的宏来为您生成这些类。

对于记录类,需要向对象添加这样的隐式val:

代码语言:javascript
复制
import reactivemongo.bson._

implicit val recordHandler: BSONHandler[BSONDocument, Record] = Macros.handler[Record]

/* Or only one of these [if your only ever writing or reading this data etc:
 implicit val recordReader: BSONDocumentReader[Record] = Macros.reader[Record]
 implicit val recordWriter: BSONDocumentWriter[Record] = Macros.writer[Record]
*/

我想说的是,试着从宏开始,看看它们是否符合你的需求。如果需要对处理/转换进行更多的控制,可以定义自己的BSONDocumentReaderBSONDocumentWriter实例。

更新的记录类

代码语言:javascript
复制
import play.api.libs.json.Json
import reactivemongo.bson._


case class Channel(label: String,amplitude: Double,position: Option[String])

object Channel {
  implicit val ChannelFormat = Json.format[Channel]
  implicit val channelHandler: BSONHandler[BSONDocument, Channel] =   Macros.handler[Channel]
 }

object RecordType extends Enumeration {
 type RecordType = Value
 val T1 = Value
 implicit val enumFormat = new Format[RecordType] {
  def reads(json: JsValue) = JsSuccess(RecordType.withName(json.as[String]))
  def writes(enum: RecordType) = JsString(enum.toString)
 }
 implicit  object RecordTypeReader extends BSONDocumentReader[RecordType] {
  def read(doc: BSONDocument) : RecordType  = {
     RecordType.withName(doc.getAs[String]("recordType").get)
  }
}
implicit object RecordTypeWriter extends BSONDocumentWriter[RecordType] {
  def write(recordType: RecordType) : BSONDocument = BSONDocument(
    "recordType" -> BSONString(recordType.toString)
  )
 }
}

case class Record(recordKey: String,recordType: RecordType.Value,channels: Map[String, Channel])

object Record {
 implicit val RecordFormat = Json.format[Record]
 implicit val recordHandler: BSONHandler[BSONDocument, Record] =  Macros.handler[Record]
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35228071

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档