Casbah Scala MongoDB驱动程序 - 从DBObject获取数据

7

好的,这是关于Casbah和MongoDB基础知识的另一个问题。当我从数据库中检索到DBObject后,如何从中提取某些数据?我知道有一个DBObject.get()方法可以返回java.lang.Object。我需要这样做然后将数据转换为所需的类型吗?我不确定这是否是最好的方法...有人能推荐一下如何更好地处理吗?

更新:

最终我选择手动处理所有内容。我不使用Salat,因为它对案例类有限制,而案例类不建议有子类,这需要架构重组。但是,答案被标记为最佳答案,因为它在大多数情况下都有效,并且这里没有其他更通用的答案。

2个回答

11

你可以使用MongoDBObject的as方法,在一个调用中获取值并进行转换:

val coll = MongoConnection()(dbName)(collName)
val query = MongoDBObject("title" -> "some value")
val obj = coll findOne query

val someStr = obj.as[String]("title")
val someInt = obj.as[Int]("count")
// and so on..

请注意,如果指定的键无法找到,as会抛出异常。您可以使用getAs,它会给您Option[A]

注意:as在未找到key时会抛出异常。您可以使用getAs方法获取Option[A]类型的返回值:

obj.getAs[String]("title") match {
    case Some(someStr) => ...
    case None => ...
}

提取列表要稍微复杂一些:

val myListOfInts =
  (List() ++ obj("nums").asInstanceOf[BasicDBList]) map { _.asInstanceOf[Int] }

我写了一个帮助程序,可以使使用casbah更简洁,也许会有帮助,因此我附上它:

package utils

import com.mongodb.casbah.Imports._

class DBObjectHelper(underlying: DBObject) {

  def asString(key: String) = underlying.as[String](key)

  def asDouble(key: String) = underlying.as[Double](key)

  def asInt(key: String) = underlying.as[Int](key)

  def asList[A](key: String) =
    (List() ++ underlying(key).asInstanceOf[BasicDBList]) map { _.asInstanceOf[A] }

  def asDoubleList(key: String) = asList[Double](key)
}

object DBObjectHelper {

  implicit def toDBObjectHelper(obj: DBObject) = new DBObjectHelper(obj)

}

您可以像这样使用辅助函数:

val someStr = obj asString "title"
val someInt = obj asInt "count"
val myDoubleList = obj asDoubleList "coords"

我希望它能帮到你。


哇,这个主题讲得非常好!谢谢,显然现在被选为最佳答案。 - noncom
当调用 val obj = coll.findOne(query); val str = obj.getAs[String]("myValue") 时,我会收到 value getAs is not a member of Option[coll.T] 的错误提示。 - Kevin Meredith
这个例子不起作用,findOne 返回一个 Option 类型。 - andyczerwonka

2
如果您不介意使用额外的依赖项,请使用Salat。 使用Salat将case类转换为数据库对象并返回非常简单。
序列化
val dbo = grater[Company].asDBObject(company)

反序列化
val company_* = grater[Company].asObject(dbo)

是的,我知道关于Salat...不害怕使用依赖关系,但是case-class的唯一要求可能会带来一些麻烦。如果没有其他有意义的答案,那么我将不得不去了解Salat...但是case-classes可能会导致需要更改架构。 - noncom

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接