Skip to content

Conversation

@prestonvasquez
Copy link
Member

GODRIVER-3697

Summary

Add Decoder.DefaultDocumentMap() method to decode nested documents as map[string]any instead of bson.M.

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().

Background & Motivation

In Go Driver v2, nested documents decode as bson.D by default, or bson.MwithDefaultDocumentM(). While bson.Mis defined astype M map[string]any, Go's type system treats bson.Mandmap[string]anyas distinct types. This breaks compatibility with third-party libraries expecting map[string]any (e.g.,github.com/Jeffail/gabs/v2), user code performing type assertions to map[string]any, and codebases that prohibit bson.M` usage.

The team previously noted that converting from bson.M to map[string]any is straightforward in user code. However, for deeply nested documents and arrays, this requires recursive transformation of the entire structure:

func convertBsonMToMap(v any) any {
	switch val := v.(type) {
	case bson.M:
		result := make(map[string]any, len(val))
		for k, v := range val {
			result[k] = convertBsonMToMap(v)
		}
		return result
	case map[string]any:
		for k, v := range val {
			val[k] = convertBsonMToMap(v)
		}
		return val
	case []any:
		for i, v := range val {
			val[i] = convertBsonMToMap(v)
		}
		return val
	default:
		return val
	}
}

This feature has been requested multiple times across different contexts (GODRIVER-3689, REP-6132), indicating a legitimate user need for v1-equivalent decoding behavior.

@github-actions github-actions bot added the documentation Pull requests that update documentation or examples label Nov 12, 2025
@mongodb-drivers-pr-bot
Copy link
Contributor

API Change Report

./v2/bson

compatible changes

(*Decoder).DefaultDocumentMap: added

./v2/mongo/options

compatible changes

BSONOptions.DefaultDocumentMap: added

@mongodb-drivers-pr-bot
Copy link
Contributor

🧪 Performance Results

Commit SHA: c383b84

The following benchmark tests for version 6914eac4af54450007cb4ca2 had statistically significant changes (i.e., |z-score| > 1.96):

Benchmark Measurement % Change Patch Value Stable Region H-Score Z-Score
BenchmarkLargeDocInsertOne ops_per_second_min -45.0718 837.0688 Avg: 1523.9335
Med: 1582.5664
Stdev: 283.8410
0.7862 -2.4199
BenchmarkMultiFindMany total_bytes_allocated -15.7282 640546472.0000 Avg: 760096146.2222
Med: 763743356.0000
Stdev: 36028084.7754
0.8358 -3.3182
BenchmarkMultiFindMany total_mem_allocs -15.6347 394805.0000 Avg: 467970.6111
Med: 469972.5000
Stdev: 22195.9290
0.8339 -3.2964
BenchmarkSingleFindOneByID total_time_seconds 12.5196 1.2925 Avg: 1.1487
Med: 1.1565
Stdev: 0.0484
0.8126 2.9729
BenchmarkSingleFindOneByID ns_per_op 11.1023 275580.0000 Avg: 248041.6667
Med: 245291.5000
Stdev: 9313.5443
0.8211 2.9568
BenchmarkSingleFindOneByID ops_per_second_med -10.3113 3714.5723 Avg: 4141.6265
Med: 4181.5366
Stdev: 147.9204
0.8199 -2.8871
BenchmarkBSONFullDocumentEncoding ops_per_second_med 3.0859 47481.1263 Avg: 46059.7459
Med: 46031.1550
Stdev: 518.0339
0.8046 2.7438
BenchmarkBSONDeepDocumentDecoding ops_per_second_med 2.9910 17228.0127 Avg: 16727.6923
Med: 16714.3028
Stdev: 242.4897
0.7632 2.0633
BenchmarkBSONDeepDocumentEncoding total_time_seconds -1.5744 1.1761 Avg: 1.1949
Med: 1.1946
Stdev: 0.0073
0.7862 -2.5598
BenchmarkLargeDocInsertOne allocated_bytes_per_op -0.2549 5675.0000 Avg: 5689.5000
Med: 5688.5000
Stdev: 4.7958
0.8448 -3.0235
BenchmarkSingleFindOneByID allocated_bytes_per_op -0.1926 22414.0000 Avg: 22457.2500
Med: 22453.0000
Stdev: 21.1930
0.7276 -2.0408
BenchmarkBSONDeepDocumentDecoding allocated_bytes_per_op -0.0086 15098.0000 Avg: 15099.3000
Med: 15099.0000
Stdev: 0.4830
0.8385 -2.6913

For a comprehensive view of all microbenchmark results for this PR's commit, please check out the Evergreen perf task for this patch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Pull requests that update documentation or examples

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant