As similarly expressed in
GODRIVER-971 (and added support for via mgocompat in GODRIVER-1362), the default behavior of the default registry used by the Go library is that an empty array (initialized but no elements) or nil array (uninitialized) becomes null when encoded to BSON, and stored in Mongo.
The primary issue with this, is that things like $push, $in, $addToSet, etc do not work as expected when the value is set to null.
The two current solutions are:
- Use mgocompat registry – a feature that's not very obvious, and it further strays away from the "recommended" approach to using the library. This however works as expected, writing an empty array into mongo.
- Use "omitempty" on the field, which doesn't write the field at all
- Most methods (e.g. $push, $addToSet, etc) work when the field doesn't exist, and those methods will create the field.
- It's not obvious that this would be needed to prevent the issue, so users would likely deploy and start writing data before realizing that this may not do what they expect. One would have to first do a database migration to remove all fields that are supposed to be arrays (which were written as null, as this isn't what they were expecting), and then add the necessary tag field for future writes.
- There are still some edge-cases with this approach I think in terms of validation (i.e. a field that is required, but can be empty, now can't be required in schema, among others), which would have to be written around in code.
Given the field being written as an empty array via bson, can be converted back to nil on the Go side, I don't believe there is a downside in taking the mgocompat approach, and bringing this in as the default. This would also ensure standard methods are prone to work as expected, play better with folks who are using validation, and seems more obvious.
At a minimum, I wish this would be re-visited, given the nature of how Go arrays have a nil zero value, which isn't necessarily common with some of the other languages which are supported, and thus I think may warrant an exception to the standard "take exactly what we're given" bson encoding semantics.