扩展为MongoDB Scala驱动程序?

时间:2019-05-28 13:27:31

标签: mongodb scala casbah

Casbah具有expand函数,可让您检索嵌套键。 较新的MongoDB Scala Driver是否具有此功能?

2 个答案:

答案 0 :(得分:1)

在Scala MongoDB驱动程序中,您可以使用宏从您的 案例类 生成编解码器。甚至您也可以为您的副产品创建编解码器(密封特性)。根据文档:“支持简单案例类和嵌套案例类。” 。因此,请看示例here

ReactiveMongo也使用宏,但是还有其他使用Shapeless的替代方法,例如: https://github.com/julienrf/reactivemongo-derived-codecs

答案 1 :(得分:0)

package org.mongodb.scala.bson

import org.mongodb.scala.bson.DefaultHelper.DefaultsTo

import scala.reflect.ClassTag
import scala.util.Try
import scala.collection.JavaConverters._

object Expandable {
  implicit class AddExpand(val underlying: Document) extends AnyVal {
    def expand[TResult <: BsonValue: ClassTag](key: String)(implicit e: TResult DefaultsTo BsonValue): Either[Throwable, TResult] = {
      val path = key.split('.')
      path.init.tail
        .foldLeft(Try(underlying.underlying.get(path.head).asDocument()).toEither){
          case (parent, pathEl) => parent.flatMap(p => get[BsonDocument](p, pathEl))
        }
        .flatMap(p => get[TResult](p, path.last))
    }
  }

  def get[TResult <: BsonValue](parent: BsonDocument, key: String)(implicit e: TResult DefaultsTo BsonValue, ct: ClassTag[TResult]): Either[Throwable, TResult] = {
    Try(parent.asScala.get(key).map(ct.runtimeClass.cast).map(_.asInstanceOf[TResult]).getOrElse(throw new NoSuchElementException(key))).toEither
  }
}

此解决方案更符合Casbah最初的扩展功能的精神。它使用extension method pattern

不确定它是否比案例类解决方案中的宏更好。我只是在文档中没有_t。

我确实使用宏和案例类以及自定义调用codecRegistry来提出一个自定义编解码器,但是它变得越来越难看。比上面显示的扩展扩展方法更丑。

与宏解决方案相比,这类型安全性较差,但如果不脏的话,可以更快地完成工作。更快,因为我不必将整个模式重写为case类。

基于MongoDB Scala Driver version 2.6.0

应该将其设置为适当的拉取请求,但可能由于某种原因而被拒绝。