I am trying to model a product for my mongodb collection "products".
So it looks like this:
{
"_id": "abc123",
"sku": "sku123",
"name": "some product name",
"description": "this is a description",
"specifications": {
"name" : "name1",
"metadata": [
{"name1": "value1"},
{"name2": "value2"},
]
}
}
So my case classes would look like:
case class Product(
id: String,
sku: String,
name: String,
description: String,
specifications: Specification
)
case class Specification(
name: String,
metadata: Metadata
)
case class Metadata(
kvp: Map[String, String]
)
So now I will have to create handlers for each type Product, Specification and Metadata so when data is read/written to mongo it will perform the correct data mapping?
How will I map the Metadata case class, a little confused?
As indicated in the documentation, the Reader
/Writer
can be simply generated most of the time.
import reactivemongo.api.bson._
// Add in Metadata companion object to be in default implicit scope
implicit val metadataHandler: BSONDocumentHandler[Metadata] = Macros.handler
// Add in Specification companion object to be in default implicit scope
implicit val specHandler: BSONDocumentHandler[Specification] = Macros.handler
// Add in Product companion object to be in default implicit scope
implicit val productHandler: BSONDocumentHandler[Product] = Macros.handler
Then any function using the BSON Reader
/Writer
typeclasses will accept Product
/Specification
/Metadata
:
BSON.writeDocument(Product(
id = "X",
sku = "Y",
name = "Z",
description = "...",
specifications = Specification(
name = "Lorem",
metadata = Metadata(Map("foo" -> "bar"))))).foreach { doc: BSONDocument =>
println(BSONDocument pretty doc)
}
/* {
'id': 'X',
'sku': 'Y',
'name': 'Z',
'description': '...',
'specifications': {
'name': 'Lorem',
'metadata': {
'kvp': {
'foo': 'bar'
}
}
}
} */