简体   繁体   中英

Magnet pattern for Scala MongoDB driver

The documentation describes using the ma.net pattern to get implicit conversion to BSON types. See on this page http://mongodb.github.io/mongo-java-driver/4.1/driver-scala/bson/scala-documents/ . I have tried defining an implicit object that extends BsonTransformer, but it fails to find a codec for the type. Am I missing something / has someone got this working? Sample code below, assume the insert method is being called.

case class CustomType(specialString: String)

implicit object TransformCustomType extends BsonTransformer[CustomType] {

  def apply(value: CustomType): BsonString = 
      BsonString(value.specialString)
}

lazy val db: MongoDatabase = client.getDatabase(dbName).withCodecRegistry(DEFAULT_CODEC_REGISTRY)
lazy val testCollection: MongoCollection[CustomType] = db.getCollection[CustomType](collectionName)

def insert: Future[Completed] = testCollection.insertOne(CustomType("a")).toFuture

Error - org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class com.bla.BlaClass$CustomType.

*note that I am aware this can be done with

val codecRegistry = fromRegistries(fromProviders(classOf[CustomType]))

but I am just using this example to ask to learn the ma.net pattern for a messier case.

If there is an implicit BsonTransformer[T] (instance of type class BsonTransformer ) in a scope then there are implicit conversions

  • T => CanBeBsonValue ( CanBeBsonValue is a wrapper over BsonValue ),

  • (String, T) => CanBeBsonElement ( CanBeBsonElement is a wrapper over BsonElement , which is a "tuple" of String and BsonValue ),

  • Iterable[(String, T)] => CanBeBsonElements ( CanBeBsonElements is a wrapper over Iterable[BsonElement] )

defined in BsonMa.nets ( CanBeBsonValue , CanBeBsonElement , CanBeBsonElements are ma.nets 1 2 ).

Then Document can be created via factory methods

def apply(elems: CanBeBsonElement*): Document

def apply(elem: CanBeBsonElements): Document

So try

val doc = Document("a" -> CustomType("bb"))

val testCollection: MongoCollection[Document] = ???

testCollection.insertOne(doc)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM