2015-07-21 37 views
1

使用ReactiveMongo驅動程序我試圖序列化可能未知的鍵/字段 混合類型Map[String, Any]到一個BSONDocument。我的問題與詢問here的問題很相似,它指的是序列化地圖here的ReactiveMongo文檔示例。不幸的是,答案似乎只適用於一致類型的地圖,而我需要它的任何。我MapWriter如下:ReactiveMongo混合類型映射到BSONDocument

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) 
     } 
    } 

下面的編譯和序列化就好了,因爲所有類型INTS

val allInts = Map("someInt" -> 1, "someOtherInt" -> 2) 
val docFromMap: BSONDocument = BSON.writeDocument(allInts)  

但是我似乎無法按摩到的東西,將處理Map[String,Any]

val mixedTypes = Map("someDouble" -> 234.324, "someString" -> "abc", "someInt" -> 1) 
val docFromMap: BSONDocument = BSON.writeDocument(mixedTypes) 

結果於:

Error:(134, 54) could not find implicit value for parameter writer: reactivemongo.bson.BSONWriter[scala.collection.immutable.Map[String,Any],reactivemongo.bson.BSONDocument] 
val docFromMap: BSONDocument = BSON.writeDocument(mixedTypes) 
               ^

爲了達到這個目的,我可能會忽略一些基本的含義概念,而不必在編譯時明確知道映射中每個字段的類型。

+0

隱含有用於類型類,其並不是魔術,但正如所說的要求一致的類型,而不是「任何」。要麼你可以用類型安全的東西來替換地圖,要麼你可以用'JsObject'(它可以從JSON語義中發現的類型的地圖)替換它。 – cchantep

回答

2

接受cchantep的建議,我走下了通過匹配地圖中的不同類型並將它們寫入文檔來更明確地進行類型安全的道路。這當然可以擴展來處理嵌套的地圖和數組。這裏可以看到一個很好的例子:JsBSONHandler Gist。對於混合型的平面地圖上面列出我的情況下,這只是正常的,我關心的值類型:

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 
}) 

用法:

val mixedTypes = Map("someDouble" -> 234.324, "someString" -> "abc", "someInt" -> 1) 
val docFromMap: BSONDocument = writeObject(mixedTypes) 
+0

謝謝了。這對我有效。 –