-
Type:
New Feature
-
Resolution: Unresolved
-
Priority:
Unknown
-
Affects Version/s: None
-
Component/s: None
-
None
-
None
-
Go Drivers
-
None
-
None
-
None
-
None
-
None
-
None
Summary
In v2, nested documents decode as bson.D by default, or bson.M with DefaultDocumentM(). While bson.M is defined as type M map[string]any, Go's type system treats bson.M and map[string]any as distinct types. This breaks compatibility with both internal and third-party libraries (e.g., github.com/Jeffail/gabs/v2) that expect map[string]any, user code that type-asserts nested values to map[string]any, and codebases that prohibit bson.M usage (e.g. mongosync).
While it's fairly straight-forward to convert bson.M to map[string]any, it would be convenient for users to avoid this step as michael.mcclimon@mongodb.com correctly notes in GODRIVER-3576. The difference between 3576 and GODRIVER-3689 is that github.com/Jeffail/gabs/v2 doesn't actually take a dependency on the driver, rather it's a generic parser that simply checks for map[string]any in a type switch. Such cases have not been previously considered by the team.
Derived from matt.dale@mongodb.com's repro, we expect the following test to pass for github.com/Jeffail/gabs/v2:
func TestWithDefaultDocumentMap(t *testing.T) {
var m map[string]any
dec := bson.NewDecoder(bson.NewDocumentReader(bytes.NewReader(testData)))
dec.DefaultDocumentMap()
err := dec.Decode(&m)
require.NoError(t, err)
// Nested values should be map[string]any, not bson.M
_, ok := m["bar"].(map[string]any)
require.True(t, ok, "Expected m[\"bar\"] to be map[string]any, got %T", m["bar"])
// Gabs should be able to access nested values
blahValue := gabs.Wrap(m).Search("bar", "blah").Data()
require.Equal(t, "x", blahValue)
}
Acceptance Criterion
- Add a DefaultDocumentMap() method to the bson.Decoder that causes the decoder to always unmarshal documents into the map[string]any type.
- Extend the migration guide and bson examples to reflect this use case.
Pitfalls
Suggest not documenting precedence between BSONOptions and bson.Decoder methods to reduce cognitive load. It's not realistic that a user would call both DefaultDocumentMap() and DefaultDocumentM().
- duplicates
-
GODRIVER-3576 Add a way to unmarshal BSON to map[string]any
-
- Closed
-
- fixes
-
GODRIVER-3689 bson.unmarshall type changed between v1 and v2
-
- Waiting for Reporter
-