I am having difficulty with the way optional values are handled by BSONDocuments in an application. I started with the "eventual" template from Typesafe activator (play/reactivemongo/angular). I created a case class representing an object to go into Mongo, and some of the values are Options:
case class Item(
id: Option[BSONObjectID],
manufacturer: String,
minPrice: Option[Double],
maxPrice: Option[Double])
The problem I am having is that the optional values are getting written to Mongo as arrays. For example purposes, use "Acme" as the manufacturer, 88 as the minPrice and None as the maxPrice. Printjson in Mongo shows that this looks like
{
_id = BSONObjectID("...")
manufacturer: "Acme",
maxPrice: [ ],
minPrice: [
88
]
}
I can't read back the array values from Mongo as a simple option value when creating an object from the database values.
Item(
....
bsondoc.getAs[Double]("minPrice"),
....
)
That getAs() statement always returns None, although bsondoc.get("minPrice") does have the value Some(BSONDocument())
I printed the data being sent to Mongo for an update, and sure enough, the code that creates the modifier statement is sending the optional value as an array, either empty, or containing one element.
val modifier = BSONDocument(
"$set" -> BSONDocument(
"manufacturer" -> manufacturer,
"minPrice" -> minPrice,
"maxPrice" -> maxPrice
))
This pretty prints as
{
$set: {
manufacturer: BSONString(Acme),
maxPrice: [
],
minPrice: [
0: BSONDouble(88.0)
]
}
}
Is there are right way to be handling these optional values?
To add to the mystery, I put the same modifier-creating code in a worksheet (in Eclipse), and I get a different result:
{
$set: {
manufacturer = BSONString(Acme),
minPrice = BSONInteger(88)
}
}
The optional values do not have an array. If they are none, they don't appear. This would work fine for my application, but something is changing the BSONDocument handling of optional elements inside the application. Does anyone know why?