如何通过Casbah将带有list的scala对象转换为MongoDBObject

时间:2012-01-30 23:24:17

标签: scala mongodb casbah

我正在通过编写一个简单的应用程序来学习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)  
}  

类别是一个具有2个案例类实现的密封特征,我打算像“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将其转换为MongoDBObject?

或Casbah不是可行的方法,还有其他库可以帮助我更轻松地将其保存到MongoDB中吗?

2 个答案:

答案 0 :(得分:6)

要使用案例类,请使用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支持带有列表的案例类(here是支持的集合列表)。

答案 1 :(得分:1)

我使用自己的库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)
}

Subset知道如何序列化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