Я определил BSONDocumentWriter
s для сопоставления объектов домена (классов case) с документами BSON, которые должны сохраняться в MongoDB с использованием драйвера ReactiveMongo. Определение авторов довольно прямолинейно для классов case (хотя утомительно и подвержено ошибкам: я бы хотел, чтобы для этого было решение, подобное Salat). Однако я не могу сделать то же самое для Map[String,Any]
(где значения могут иметь тип numeric, date или string). Я нашел code example, который определяет общий писатель (и читателя) на карте:Reactivemongo сериализация карты в BSONDocument
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))
^
Если это было выполнено, я мог бы использовать некоторый базовый класс в качестве типа значения и определить его неявный писатель.
Я не уверен, почему это происходит и как я могу это решить. Может быть, мне не хватает чего-то очевидного? Идеи?
Не проверял его, потому что, к сожалению, я больше не работаю с Scala, но это имеет смысл. –