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
Post a Comment