如何创建查询数据库的自定义编写器/阅读器?

时间:2017-02-10 14:06:03

标签: scala playframework reactivemongo play-reactivemongo

我有一个班级Song和一个班级Album。我的目标是有两个单独的集合,并通过BSONObjectID在数据库中保留引用,但在我的代码中,我想将这些ID映射到它们各自的实体。

这是我现在的模特:

case class Song(var _id: Option[BSONObjectID] = None,
                   name: String,
                   albumId: BSONObjectID,
                   var created: Option[DateTime] = None,
                   var updated: Option[DateTime] = None
                  )

我想将albumId替换为album

这是我现在的模特:

case class Song(var _id: Option[BSONObjectID] = None,
                   name: String,
                   album: Album,
                   var created: Option[DateTime] = None,
                   var updated: Option[DateTime] = None
                  )

正如documentation所述,我必须为此创建自定义编写器/阅读器。但是,我的问题是我不知道如何在我的自定义读取器/写入器内查询数据库,以便检索所有必要的字段来实例化我的Album实例。这是它应该如何工作的?查询模型中的数据库?

object Song {

  import play.api.libs.json._
  import play.api.libs.json.Reads._
  import play.api.libs.functional.syntax._
  import reactivemongo.play.json.BSONFormats.BSONObjectIDFormat

  implicit val songReads: Reads[Song] = (
    (__ \ "_id").readNullable[BSONObjectID].map(_.getOrElse(BSONObjectID.generate)).map(Some(_)) and
      (__ \ "album").read[BSONObjectID].map(x => Album(_id = Option(_), ...)) and // ???
      (__ \ "created").readNullable[DateTime].map(_.getOrElse(new DateTime())).map(Some(_)) and
      (__ \ "updated").readNullable[DateTime].map(_.getOrElse(new DateTime())).map(Some(_))
    ) (Song.apply _)

  implicit val songWrites: OWrites[Song] = (
    (__ \ "_id").writeNullable[BSONObjectID] and
      (__ \ "album").write[BSONObjectID] and // ???
      (__ \ "created").writeNullable[DateTime] and
      (__ \ "updated").writeNullable[DateTime]
    ) (unlift(Song.unapply))

}

1 个答案:

答案 0 :(得分:0)

正如有人讨论的那样,ReactiveMongo中的BSONHandlers负责序列化/反序列化单个对象,而不是管理对象关系。

管理关系与序列化没什么关系,你需要编写一个单独的层来处理它。

def loadSong(songName:String) : Future[Song] = // query coll 1 then query coll2 then build Song object