how to cast a Mongo BasicDBList to an immutable scala list
I have a BasicDBList that has been persisted into the database. I am now reading the data and trying to convert the list to an immutable scala list a开发者_运维百科s shown:
val collection = mongoFactory.getCollection("tokens")
val appId = MongoDBObject("appId" -> id)
val appDBObject = collection.findOne(appId)
val scope: List[String] = appDBObject.get("scope").asInstanceOf[List[String]]
However, I am getting a class cast exception saying it is not possible to cast a BasicDBList to a Scala immutable list.
I have tried various combinations, such as converting to a map, etc. Nothing seems to work.
Because MongoDB stores Arrays the same way JavaScript does --- as an object with integer keys indicating their index --- BasicDBList is necessary internally to represent the object coming off of the wire. As such, currently Casbah doesn't automatically represent it as a Scala list.... BasicDBList is a HashMap, not a List.
HOWEVER, internally Casbah does provide implicit conversions to let you treat BasicDBList as a LinearSeq[AnyRef]; LinearSeq is a bit different on the type tree than List but a more appropriate type for a variety of reasons. Unfortunately you can't cast with implicit conversions.
For now, what I recommend is that you get the item as a DBList, and then either type annotate it as a LinearSeq which will use the implicit, or simply call toList on it (The implicit will provide the toList method).
scala> val l = MongoDBList("foo", "bar", "baz")
l: com.mongodb.BasicDBList = [ "foo" , "bar" , "baz"]
scala> val obj = MongoDBObject("list" -> l)
obj: com.mongodb.casbah.commons.Imports.DBObject = { "list" : [ "foo" , "bar" , "baz"]}
scala> obj.as[BasicDBList]("list")
res8: com.mongodb.casbah.Imports.BasicDBList = [ "foo" , "bar" , "baz"]
scala> obj.as[BasicDBList]("list").toList
res9: List[AnyRef] = List(foo, bar, baz)
The as[T]: T
and getAs[T]: Option[T]
methods are preferable, incidentally, to casting as they have some trickery inside to do type massaging. The next release of Casbah will include code so that if you ask for a Seq, List, etc and it's a DBList as
and getAs
will automatically convert them to the type you asked for.
精彩评论