Search code examples
scalareactivemongo

ReactiveMongo BSONHandler for Map


I have following class, and want to use reactivemongo.bson.Macros.handler to get the reader and writer automatically.

case class Data(a: String, b: Map[String, String])
object Data {
  implicit val dataHandler = reactivemongo.bson.Macros.handler[Data]
}

But it fails to compile, saying Implicit Map[String,String] for 'value vs' not found

How to make this work? I'm using reactivemongo_2.10 0.11.10


Solution

  • According to this gist, I find a solution as:

    case class Data(date: String, base: String, vs: Map[String, String])
    
    object Data {
      implicit object BSONMapHandler extends BSONHandler[BSONDocument, Map[String, String]] {
        override def read(bson: BSONDocument): Map[String, String] = {
          bson.elements.map {
            case (key, value) => key -> value.asInstanceOf[BSONString].value
          }.toMap
        }
    
        override def write(t: Map[String, String]): BSONDocument = {
          val stream: Stream[Try[(String, BSONString)]] = t.map {
            case (key, value) => Try((key, BSONString(value)))
          }.toStream
          BSONDocument(stream)
        }
      }
      implicit val dataHandler = reactivemongo.bson.Macros.handler[Data]
    }
    

    Don't know why reactivemongo not support it by default.