我们目前正在使用Type-Safe查询语言,这种自定义DSL允许我们轻松编写被解释并转换为Mongo查询的数据库查询。
我们最近从Casbah换成了新的Mongo Scala Driver并重写了我们的翻译。但是在处理可选值时我遇到了一些问题。
这是一个示例查询:
dao.headOption(Order.id === orderId.some)
订单对象上存储的类型是一个选项,因此我们也将提供的ID提升到一个选项中。但是,每当我尝试以下列方式呈现生成的调试以及测试用例的查询时:
import org.mongodb.scala.bson.{BsonDocument, codecs}
query.toBsonDocument(BsonDocument.getClass, codecs.DEFAULT_CODEC_REGISTRY)
以下异常最终被抛出:
Can't find a codec for class scala.Some.
org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class scala.Some.
我不确定如何纠正这个问题,或者我是否需要为Options实现自己的编解码器,如果我这样做,我不知道如何做到这一点。
任何帮助都会很高兴。 提前谢谢
更新
我已经看到我可以尝试实现Codec接口,如下所示:
http://mongodb.github.io/mongo-java-driver/3.0/bson/codecs/
我是否需要为每个可能的子类型选项实现它?
示例选项[Int],选项[UUID],选项[列表[字符串]]等。
答案 0 :(得分:4)
你可以用这样的东西来解决问题
class SomeCodec extends Codec[Some[_]] {
override def encode(writer: BsonWriter, value: Some[_], encoderContext: EncoderContext): Unit = value match {
case Some(v: String) ⇒ writer.writeString(v)
case Some(v: Int) ⇒ writer.writeInt32(v)
case Some(v: Long) ⇒ writer.writeInt64(v)
case Some(v: Boolean) ⇒ writer.writeBoolean(v)
}
override def getEncoderClass: Class[Some[_]] = classOf[Some[_]]
override def decode(reader: BsonReader, decoderContext: DecoderContext): Some[_] = {
reader.getCurrentBsonType match {
case BsonType.BOOLEAN ⇒ Some(reader.readBoolean())
case BsonType.STRING ⇒ Some(reader.readString())
case BsonType.INT64 ⇒ Some(reader.readInt64())
case BsonType.INT32 ⇒ Some(reader.readInt32())
}
}
}