我将BSONDocumentWriter
定义为将域对象(案例类)映射到要使用ReactiveMongo驱动程序在MongoDB中持久保存的BSON文档。定义编写器对于案例类来说非常简单(虽然繁琐且容易出错:我希望有类似Salat的解决方案)。但是,我似乎无法对Map[String,Any]
执行相同的操作(其值可以是numeric,date或string类型)。我找到了一个code example来定义地图的通用编写器(和读者):
implicit def MapWriter[V](implicit vw: BSONDocumentWriter[V]): 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)
}
}
但是如果类型BSONDocumentWriter
没有隐式V
,那么这不起作用,即代码段:
BSONDocument(
"_id" -> "asd",
"map" -> MapWriter[Any].write(Map("x" -> 1, "y" -> "2"))
)
无法编译:
could not find implicit value for parameter vw: reactivemongo.bson.BSONDocumentWriter[Any]
"map" -> MapWriter[Any].write(Map("x" -> 1, "y" -> "2"))
^
我想也许作者应该写一个BSONValue
而不是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)
}
}
为了简单起见,我尝试使用Int
作为值类型,但再次使用了代码段:
BSONDocument(
"_id" -> "asd",
"map" -> ValueMapWriter[Int].write(Map("x" -> 1, "y" -> 2))
)
无法编译:
could not find implicit value for parameter vw: reactivemongo.bson.BSONWriter[Int,reactivemongo.bson.BSONValue]
"map" -> ValueMapWriter[Int].write(Map("x" -> 1, "y" -> 2))
^
如果以上方法有效,我可以使用一些基类作为值类型并定义其隐式编写器。
我不确定为什么会这样,以及我如何解决它。也许我错过了一些明显的东西?想法?
答案 0 :(得分:1)
ValueMapWriter 定义中 BSONValue 的泛型类型参数边界不正确。如果你改变了行
implicit def ValueMapWriter[V](implicit vw: BSONWriter[V, BSONValue]): BSONDocumentWriter[Map[String, V]] =
带
implicit def ValueMapWriter[V](implicit vw: BSONWriter[V, _ <: BSONValue]): BSONDocumentWriter[Map[String, V]] =
然后它应该解析Int。
的隐式编写器BTW simple-reactivemongo已经这样做了。我还计划将此功能添加到ReactiveMongo Extensions。