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

发布于 2024-11-03 19:41:50 字数 414 浏览 1 评论 0原文

我有一个已保存到数据库中的 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

蓝眼泪 2024-11-10 19:41:50

因为 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自动将它们转换为您要求的类型。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文