Reactivemongo将地图序列化为BSONDocument [英] Reactivemongo serializing a map into a BSONDocument
问题描述
我定义了BSONDocumentWriter
,以使用ReactiveMongo驱动程序将域对象(案例类)映射到要保留在MongoDB中的BSON文档.为案例类别定义作者非常简单(尽管乏味且容易出错:我希望有类似Salat的解决方案).但是,我似乎无法对Map[String,Any]
(值可以是数字,日期或字符串类型)执行相同的操作.我找到了代码示例,它定义了通用编写器(和读者)以获取地图:
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)
}
}
,但是如果没有V
类型的隐式BSONDocumentWriter
,即代码段,则此方法无效:
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))
^
如果上述方法可行,我可以使用一些基类作为值类型并定义其隐式编写器.
我不确定为什么会这样以及如何解决.也许我缺少明显的东西?想法?
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扩展.>
I defined BSONDocumentWriter
s to map domain objects (case classes) to BSON documents to be persisted in MongoDB using the ReactiveMongo driver. Defining the writers is quite straight-forward for case classes (although tedious and error prone: I wish there was a Salat-like solution for that). However, I can't seem to be able to do the same for a Map[String,Any]
(where the values can be of type numeric, date or string). I found a code example that defines a generic writer (and reader) for a map:
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)
}
}
but this does not work if there's no implicit BSONDocumentWriter
for the type V
, i.e., the snippet:
BSONDocument(
"_id" -> "asd",
"map" -> MapWriter[Any].write(Map("x" -> 1, "y" -> "2"))
)
does not compile:
could not find implicit value for parameter vw: reactivemongo.bson.BSONDocumentWriter[Any]
"map" -> MapWriter[Any].write(Map("x" -> 1, "y" -> "2"))
^
I thought maybe the writer should write to a BSONValue
instead of a BSONDocument
so I modified the example as 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)
}
}
And to keep things simple, I tried to use Int
as the value type but again, the snippet:
BSONDocument(
"_id" -> "asd",
"map" -> ValueMapWriter[Int].write(Map("x" -> 1, "y" -> 2))
)
does not compile:
could not find implicit value for parameter vw: reactivemongo.bson.BSONWriter[Int,reactivemongo.bson.BSONValue]
"map" -> ValueMapWriter[Int].write(Map("x" -> 1, "y" -> 2))
^
If the above had worked I could have used some base class as the value type and defined its implicit writer.
I am not sure why this is happening and how I can solve it. Maybe I am missing something obvious? Ideas?
The generic type parameter boundary for BSONValue in ValueMapWriter definition is not correct. If you change the line
implicit def ValueMapWriter[V](implicit vw: BSONWriter[V, BSONValue]): BSONDocumentWriter[Map[String, V]] =
with
implicit def ValueMapWriter[V](implicit vw: BSONWriter[V, _ <: BSONValue]): BSONDocumentWriter[Map[String, V]] =
then it should resolve the implicit writer for Int.
BTW simple-reactivemongo already does this. And I am also planning to add this functionality to ReactiveMongo Extensions.
这篇关于Reactivemongo将地图序列化为BSONDocument的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!