2

I'm trying to fetch doc and get it's attribute. When I use findOne method, I expect to get MongoDBObject, but I receive Option[com.mongodb.DBObject]. How to get an attribute from it? Is it possible to get MongoDBObject instead of this?

scala> var col = MongoClient()("test")("counters")
col: com.mongodb.casbah.MongoCollection = MongoCollection({ "_id" : "some" , "value" : 0})

scala> var doc = col.findOne()
doc: Option[com.mongodb.DBObject] = Some({ "_id" : "some" , "value" : 0})

scala> doc("_id")
<console>:13: error: Option[com.mongodb.DBObject] does not take parameters
              doc("_id")
                 ^
scala>
un1t
  • 4,259
  • 2
  • 30
  • 33
  • possible duplicate of [Why Option\[T\] ?](http://stackoverflow.com/questions/2079170/why-optiont) – om-nom-nom Feb 17 '13 at 10:17
  • 1
    in short: use `.get` method if you 100% sure you have a value, use `.getOrElse(*somedefault*)` if you not sure, but want to provide default value in case database returned nothing. You can also use .map to transform options. – om-nom-nom Feb 17 '13 at 10:20

3 Answers3

2

Casbah API doesn't know the contents of your database and cannot be sure that record you are asking for really exists. In Java such method would simply return object that can be null. This is discouraged in Scala in faviour of safer Option[T] type. This way you are forced to handle a situation where object didn't exist. You have several syntaxes for that (from worst to best:

When you are sure object is there - otherwise exception will be thrown

col.findOne().get

When you want to handle both cases:

col.findOne() match {
  case Some(r) => //r is your record
  case None => //record didn't exist
}

When you want to perform certain operations on your record (monadic style)

col.findOne().map(r => r("_id")).foreach(println)

The code above will print the _id column only if such record was found - and do nothing otherwise.

Sergey Passichenko
  • 6,920
  • 1
  • 28
  • 29
Tomasz Nurkiewicz
  • 334,321
  • 69
  • 703
  • 674
1

You get an Option[DBObject] because of the possibility that the object you are trying to find may not be in the database.

You can process it with a match construct:

col.findOne() match{
  case Some(doc) => doc("id")
  case None => // not found
}
Eduardo
  • 8,362
  • 6
  • 38
  • 72
1

You get an Option[DBObject], because there might be none found and in general you want to avoid returning null in scala (and any other functional language). There are several ways to act on the result. To simply get the result you can call get, which will throw an exception, if you get None from your query. Then there is getOrElse, which you can use to get either the result, or a default value, that you have to pass in to the call. And then there is orNull, which returns you either the result or null, if there is none. You can also use foreach, if you only use the result to create side effects, or map, if you want to get a certain value and then for example call getOrElse on the resulting option.

drexin
  • 24,225
  • 4
  • 67
  • 81