bsonpickle is a modified version of µPickle which implicitly derives Reader
and Writer
instances for common Scala data structures (Option
, Either
, most collection classes), case classes and sealed trait hierarchies to serialize data to BSON for use with the ReactiveMongo driver.
For more details on how you use or customize bsonpickle, please refer to the µPickle documentation.
Big thanks to Li Haoyi for creating µPickle!
Add this to build.sbt
:
libraryDependencies += "name.pellet.jp" %% "bsonpickle" % <latest published version>
Release 0.4.4.2 is based on µPickle 0.4.4 and on the BSON classes found in ReactiveMongo 0.12.2.
Most probably, JSON serializers are already available for your data, and the Play plugin for ReactiveMongo allows you to use Play's JSON classes directly to interact with Mongo and MongoDB collections. While it is perfectly possible to do so, the data inserted into MongoDB that way is not always ideally represented:
- JSON makes no difference between
Int
,Long
,Double
. For some values, your JSON representation may even store them as strings. BSON stores each type in a specific type-aware container. - Additionally, BSON has dedicated ways to represent these types, which JSON doesn't:
- dates
- binary data
Moreover, representing all data with the appropriate BSON wrapper…
- enables a more compact representation in MongoDB
- enables fast type-aware queries like numerical comparisons
- enables type-aware sorting
- preserves the type information for other MongoDB drivers
- makes it show up correctly in GUI tools (such as Robomongo).
Here's how native Scala types are mapped to BSON classes from the ReactiveMongo driver out of the box. Additional mappings can of course be defined.
Scala Type | BSON Type |
---|---|
Boolean |
BSONBoolean |
String |
BSONString |
Symbol |
BSONString |
Char |
BSONString of length 1 |
Int |
BSONInteger |
Short |
BSONInteger |
Byte |
BSONInteger |
Long |
BSONLong |
Double |
BSONDouble |
Float |
BSONDouble |
java.util.Date |
BSONDateTime |
java.time.Instant |
BSONDateTime |
scala.concurrent.duration.Duration |
BSONLong storing nanoseconds, or BSONString for the special values "inf" , "-inf" and "undef" |
java.util.UUID |
BSONString |
Array[Byte] |
BSONBinary |
Tuple1 to Tuple22 |
BSONArray with a fixed size |
Collection1, 2 | BSONArray |
Map |
BSONDocument if keys are of type String , else BSONArray of BSONArray s with size 2 |
Option |
BSONArray with 0 or 1 elements |
Either |
BSONArray with 2 elements, the first of which it a BSONBoolean indicating Left or Right |
Unit, other singletons | empty BSONDocument |
Case classes1, 3 | BSONDocument |
Sealed trait hiearchies1, 4 | BSONDocument |
Notes
- Provided the values it contains can themselves be represented as BSON.
- “Collection” here means any generic type
V
containing elements of typeT
for which aCanBuildFrom[Nothing, T, V[T]]
is implicitly available. - If you’ve defined custom field names with the
derive.key
annotation, they will be picked up by both µPickle and bsonpickle. - Concrete type information is stored in a field named
"_type"
(and not"$type"
as µPickle does, as MongoDB disallows the use of the dollar character in field names). This is customizable.
bsonpickle is heavily based on µPickle's code. Therefore, its version number reflects the version number of µPickle is it based on. The last segment indicates iterations within bsonpickle. For instance, bsonpickle version 0.3.9.1 is iteration 1 of the library based on µPickle 0.3.9. As both µPickle and bsonpickle are closely tied to the Li Haoyi's derive
library, you may run into problems if you use them both with different reference versions.