Ok, so here is another question on basics of Casbah and MongoDB. After I have retreived a DBObject from database, how do I extract certain data from it? I know that there is the DBObject.get()
method, that returns java.lang.Object
. Do I have to do it like this and then just cast the data to the needed type? I am not sure that this is the best way to do it... can anyone recommend on how to do this better?
UPDATE:
Finally I went the way of manually handling all the stuff. I am not using Salat because of the case class limitation because case classes are not recommended for having children and that would require architectural rearrangement. However, the answer is marked as the best answer, since it would work in most situations and there is no other more general answer here.
You can use MongoDBObject's as
method to get value and cast it in one call:
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..
Note that as
throws an exception if given key cannot be found. You may use getAs
which gives you Option[A]
:
obj.getAs[String]("title") match {
case Some(someStr) => ...
case None => ...
}
Extracting lists is a bit more complicated:
val myListOfInts =
(List() ++ obj("nums").asInstanceOf[BasicDBList]) map { _.asInstanceOf[Int] }
I wrote a helper, which makes using casbah more consice, may be it will be helpful, so I attach it:
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)
}
You can use helper like this:
val someStr = obj asString "title"
val someInt = obj asInt "count"
val myDoubleList = obj asDoubleList "coords"
I hope it will help you.
If you're not afraid of using additional dependencies, use Salat. With Salat it is really simple to cast case classes to database object and back.
serialization
val dbo = grater[Company].asDBObject(company)
deserialization
val company_* = grater[Company].asObject(dbo)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With