如何将 Mongo BasicDBList 转换为不可变的 scala 列表
我有一个已保存到数据库中的 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 不可变列表。
我尝试了各种组合,例如转换为地图等。似乎没有任何效果。
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 as 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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
因为 MongoDB 存储数组的方式与 JavaScript 相同——作为一个带有指示其索引的整数键的对象——BasicDBList 在内部是必要的,用于表示来自网络的对象。因此,目前 Casbah 不会自动将其表示为 Scala 列表......BasicDBList 是 HashMap,而不是 List。
然而,Casbah 内部确实提供了隐式转换,让您将 BasicDBList 视为 LinearSeq[AnyRef]; LinearSeq 在类型树上与 List 略有不同,但出于多种原因,它是更合适的类型。不幸的是,您无法使用隐式转换强制转换。
目前,我建议您将项目作为 DBList 获取,然后将其注释为 LinearSeq(将使用隐式),或者简单地调用 toList (隐式将提供 toList 方法)。
顺便说一句,
as[T]: T
和getAs[T]: Option[T]
方法比强制转换更可取,因为它们内部有一些技巧来进行类型按摩。 Casbah 的下一个版本将包含这样的代码:如果您请求 Seq、List 等并且它是 DBListas
和getAs
将自动将它们转换为您要求的类型。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).
The
as[T]: T
andgetAs[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 DBListas
andgetAs
will automatically convert them to the type you asked for.