0

I am new to Casbah and scala. How can i access nested document in scala? I have few fields defined here and as you can see Currency and Ratios are nested document. When I am trying to print Currency.ExchangeCCY it gives me an error. How can i get specific value value rather than whole of nested object?

val query = MongoDBObject("RunDate" -> "18-02-2015")                      
val fields = MongoDBObject("Currency.ExchangeCCY" -> 1,         
                           "Currency.MarketCapCCY" -> 1)

for (d <- price.find(query,fields))  println(d("Currency"))
//> { "ExchangeCCY" : "CAD" , "MarketCapCCY" : "CAD"}
//| { "ExchangeCCY" : "CAD" , "MarketCapCCY" : "CAD"}
Pascal Bugnion
  • 4,878
  • 1
  • 24
  • 29
user3341078
  • 449
  • 1
  • 5
  • 16

1 Answers1

2

You can access a sub-document using d.getAs[DBObject] or d.getAsOrElse[DBObject]. This returns another DBObject, from which you can query the specific field.

In your case, ignoring error handling for now,

val currencyDocument = d.getAs[DBObject]("Currency").get
val exchangeCcy = currencyDocument("ExchangeCCY")

There are a couple of problems with this approach. The most glaring one is the compile-time type of exchangeCcy. If you look at the Casbah Scaladocs, you will see that it has type AnyRef. If you think that this should always be a string, you can enforce this with:

val exchangeCcy = currencyDocument.getAs[String]("ExchangeCCY").get

exhangeCcy is now guaranteed to be a string.

What about error handling? What if we can't cast Currency to a DBObject, or exhangeCcy to a String? The clue is in getAs. This returns a Scala option which is either Some(value) or None if the cast failed. A fault tolerant way of reading the Currency sub-document would therefore be:

val currencyDocument = d.getAs[DBObject]("Currency") match {
    case Some(v) => v
    case None => throw new IllegalStateException(
        "Failed to read 'Currency'")
    }
Pascal Bugnion
  • 4,878
  • 1
  • 24
  • 29
  • No problem. You might consider reading this: http://stackoverflow.com/help/someone-answers . If you accept answers, it will make people more likely to help you in the future. – Pascal Bugnion Feb 20 '15 at 16:59