如何将Mongo BasicDBList转换为不可变的scala列表

时间:2011-04-25 15:41:22

标签: scala mongodb casbah

我有一个已经持久存储到数据库中的BasicDBList。我现在正在读取数据并尝试将列表转换为不可变的scala列表,如下所示:

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]]

但是,我得到一个类转换异常,说不可能将BasicDBList转换为Scala不可变列表。

我尝试了各种组合,例如转换为地图等。似乎没什么用。

1 个答案:

答案 0 :(得分:12)

因为MongoDB以与JavaScript相同的方式存储数组 - 作为具有指示其索引的整数键的对象---在内部需要BasicDBList来表示来自线路的对象。因此,目前Casbah不会自动将其表示为Scala列表.... BasicDBList是一个HashMap,而不是List。

但是,内部Casbah确实提供了隐式转换,让您将BasicDBList视为LinearSeq [AnyRef]; LinearSeq在类型树上有点不同于List,但由于各种原因,它是更合适的类型。很遗憾,您无法使用隐式转换投射

现在,我建议您将项目作为DBList获取,然后键入将其注释为将使用隐式的LinearSeq,或者只是在其上调用toList(隐式将提供toList方法)。

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)

顺便提一下,as[T]: TgetAs[T]: Option[T]方法更适合于施法,因为他们内部有一些技巧来进行类型按摩。 Casbah的下一个版本将包含代码,这样如果你要求Seq,List等,它是一个DBList asgetAs自动将它们转换为你的类型要求。