Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Casbah Scala MongoDB driver - getting data from a DBObject

Tags:

mongodb

casbah

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.

like image 949
noncom Avatar asked May 06 '12 11:05

noncom


2 Answers

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.

like image 78
lambdas Avatar answered Nov 24 '22 11:11

lambdas


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)
like image 23
om-nom-nom Avatar answered Nov 24 '22 10:11

om-nom-nom