如何通过Casbah将带有列表的scala对象转换为MongoDB对象



我正在通过编写一个简单的应用程序学习MongoDB和Casbah。当我试图将一个具有列表成员的对象转换为MongoDB对象时,遇到了问题。这是我的班级

case class BorrowerRecord( name: String, checkedOut: List[BookTag]) {
  require(!name.isEmpty)
  require(!checkedOut.isEmpty)
}
case class BookTag (subject: Subject, bookName: String) {
  require(!bookName.isEmpty)
}
case class Subject (name: String, category: Category) {
  require(!name.isEmpty)  
}  

Category是一个封闭的特性,有2个case类实现,我打算像使用"Enum"一样使用它

sealed trait Category {
  def name: String
}
object Category {
  case object Computing extends Category { val name = "Computing"}
  case object Math extends Category { val name = "Math"}
}

因此,BorrowerRecord的一个实例将保存一个人从图书馆签出的书,每本书都由BookTag对象标识。BookTag保存一些关于书籍的信息,如书名、主题名称、类别等。

假设我有一个BorrowerRecord,并想将其保存到MongoDB

val borrowOnToday = BorrowerRecord( "My Name", List( BookTag(Subject("J2EE", Category.Computing), "Head First Java"), 
                                                     BookTag(Subject("Linear Algebra", Category.Math), "Algebra for Dummies")))

我应该如何使用Casbah将其转换为MongoDB对象?

或者Casbah不是一条路,还有其他库可以帮助我更容易地将其持久化到MongoDB中?

要使用案例类,请使用salat(按<-和->在演示文稿中移动)。

很简单:

case class Alpha(x: String)
scala> val a = Alpha(x = "Hello world")
a: com.novus.salat.test.model.Alpha = Alpha(Hello world)
scala> val dbo = grater[Alpha].asDBObject(a)
dbo: com.mongodb.casbah.Imports.DBObject = { "_typeHint" : 
    "com.novus.salat.test.model.Alpha" , "x" : "Hello world"}
scala> val a_* = grater[Alpha].asObject(dbo)
a_*: com.novus.salat.test.model.Alpha = Alpha(Hello world)

通常,我同时使用它们:casbah用于向Mongo查询,salat用于转换为case类,反之亦然。

是的,salat支持带有Lists的case类(这是支持的集合的列表)。

我使用自己的库Subset(我最近开源了它)和MongoDB Java驱动程序。与Salat不同,它是显式的,您必须声明所有的序列化代码,尽管Subset有助于保持它非常简单。您将获得创建查询的能力作为奖励。

对于您的数据模型,代码可能看起来像

object BorrowerRecord {
  val name = "name".fieldOf[String]
  val checkedOut = "cout".fieldOf[List[BookTag]]
  def toDBO(rec: BorrowerRecord): DBObject =
    name(rec.name) ~ checkedOut(rec.checkedOut)
}

子集知道如何序列化List[T],但它需要一个隐式的ValueWriter[BookTag]

object BookTag {
  val subject = "subj".fieldOf[Subject]
  val name = "name".fieldOf[String]
  implicit def writer = ValueWriter[BookTag](bt =>
    (subject(bt.subject) ~ name(bt.name)).get
  )
}

我希望您有继续使用SubjectCategory

的想法

最新更新