Context
There have been multiple clarification inquiries about the v2 bson.M unmarshaling behavior changes. e.g. this thread
Consider the following code:
func main() { b1 := bson.M{"a": 1, "b": bson.M{"c": 2}} fmt.Printf("b1: %v\n", b1) fmt.Printf("b1.b %v %T\n", b1["b"], b1["b"]) b2, err := bson.Marshal(b1) if err != nil { fmt.Println(err) return } fmt.Printf("b2: %v\n", b2) b3 := bson.M{} err = bson.Unmarshal(b2, &b3) if err != nil { fmt.Println(err) return } fmt.Printf("b3: %v\n", b3) fmt.Printf("b3.b %v %T\n", b3["b"], b3["b"]) }
//v1
b1: map[a:1 b:map[c:2]]
b1.b map[c:2] primitive.M
b2: [27 0 0 0 16 97 0 1 0 0 0 3 98 0 12 0 0 0 16 99 0 2 0 0 0 0 0]
b3: map[a:1 b:map[c:2]]
b3.b map[c:2] primitive.M
//v2
b1: {"a":Unknown macro: {"$numberInt"},"b":{"c":
Unknown macro: {"$numberInt"}}}
b1.b {"c":{"$numberInt":"2"}} bson.M
b2: [27 0 0 0 3 98 0 12 0 0 0 16 99 0 2 0 0 0 0 16 97 0 1 0 0 0 0]
b3: {"a":Unknown macro: {"$numberInt"},"b":{"c":
Unknown macro: {"$numberInt"}}}
b3.b {"c":{"$numberInt":"2"}} bson.D
Because a document is always decoded into a bson.D by default in v2. (more details in GODRIVER-2819)
However, the migration guide did not mention the behavior change clearly except here ambiguously. We need to call that out more clearly in the migration guide. And explain how to unmarshal into a bson.M using Decode, or SetBSONOptions.
Definition of done
v2 migration guide explicitly calls out the behavior changes.
Pitfalls
What should the implementer watch out for? What are the risks?