scala - ReactiveMongo mixed type map to BSONDocument -


using reactivemongo driver trying serialize map of potentially unknown keys/fields of mixed types map[string, any] bsondocument. question quite similar asked here refers reactivemongo documentation example of serializing maps here. unfortunately answer seems work maps of consistent type whereas need any. mapwriter follows:

implicit def valuemapwriter[v](implicit vw: bsonwriter[v, _ <: bsonvalue]): bsondocumentwriter[map[string, v]] =     new bsondocumentwriter[map[string, v]] {       def write(map: map[string, v]): bsondocument = {         val elements = map.tostream.map {           tuple =>             tuple._1 -> vw.write(tuple._2)         }         bsondocument(elements)       }     } 

the following compiles , serializes fine types ints

val allints = map("someint" -> 1, "someotherint" -> 2) val docfrommap: bsondocument = bson.writedocument(allints)     

however cannot seem massage handle map[string,any]

val mixedtypes = map("somedouble" -> 234.324, "somestring" -> "abc", "someint" -> 1) val docfrommap: bsondocument = bson.writedocument(mixedtypes) 

results in:

error:(134, 54) not find implicit value parameter writer: reactivemongo.bson.bsonwriter[scala.collection.immutable.map[string,any],reactivemongo.bson.bsondocument] val docfrommap: bsondocument = bson.writedocument(mixedtypes)                                                  ^ 

there fundamental concept of implicits i'm missing in order accomplish this, without explicitly knowing types of each field in map @ compile time.

taking advice cchantep, went down road of making things more explicitly typesafe matching different types in map , writing them document. can expanded handle nested maps , arrays. example of can seen here: jsbsonhandler gist. scenario listed above flat map of mixed types, works fine value types care about:

def writeobject(obj: map[string,any]): bsondocument = bsondocument(obj.map(writepair))  def writepair(p: (string, any)): (string, bsonvalue) = (p._1, p._2 match     {     case value: string  => bsonstring(value)     case value: double  => bsondouble(value)     case value: int     => bsoninteger(value)     case value: boolean => bsonboolean(value)     case value: long    => bsonlong(value)     case other => bsonnull }) 

usage:

val mixedtypes = map("somedouble" -> 234.324, "somestring" -> "abc", "someint" -> 1) val docfrommap: bsondocument = writeobject(mixedtypes) 

Comments