[GODRIVER-1608] Reordered fields in bson.M document Created: 07/May/20  Updated: 27/Oct/23  Resolved: 09/May/20

Status: Closed
Project: Go Driver
Component/s: BSON
Affects Version/s: 1.3.3
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: Old Old Assignee: Unassigned
Resolution: Works as Designed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

ubuntu 18.04
go 1.14
MongoDB server version 4.2.5



 Description   

 

Hi,

I've noticed a weird behavior when decoding result to bson.M

for some reason, all the field of the bson.M document are sorted when fetched from a collection. Not sure if the reordering happens during Find or Decode though

go code to reproduce the issue:

 

package main
import (
 "context"
 "fmt"
 "go.mongodb.org/mongo-driver/bson"
 "go.mongodb.org/mongo-driver/mongo"
 "go.mongodb.org/mongo-driver/mongo/options"
)
func main() {
client, _ := mongo.Connect(context.Background(), options.Client().ApplyURI("mongodb://localhost:27017"))
doc := bson.M{
 "b": 1,
 "a": 2,
 }
c := client.Database("test").Collection("collection")
 c.Drop(context.Background())
c.InsertOne(context.Background(), doc)
result := bson.M{}
cursor, _ := c.Find(context.Background(), bson.M{})
 if cursor.Next(context.Background()) {
 cursor.Decode(result)
 }
fmt.Printf("%+v", result)
client.Disconnect(context.Background())
}

output:

 

map[_id:ObjectID("5eb498f45f45605b861334f4") a:2 b:1]

 

 expected behavior (mongo shell): the field order should not change

 

> use test
switched to db test
> db.collection.drop()
true
> db.test.insert({"b":1, "a":2})
WriteResult({ "nInserted" : 1 })
> db.test.find()
{ "_id" : ObjectId("5eb4993ff3c0910e14193d5b"), "b" : 1, "a" : 2 }

 

the old mgo driver was not changing the field order

This was initially noticed here:  mongoplayground.net/p/6--axoMYpDZ



 Comments   
Comment by Divjot Arora (Inactive) [ 09/May/20 ]

No worries, thanks for confirming. I'm going to close this ticket as "works as designed" but feel free to leave a comment or open a new ticket if you have further questions.

Comment by Old Old [ 08/May/20 ]

Hi @Divjot Arora,

Thank you for the quick answer. You're totally right, this is unrelated to the mongo-go-driver, I forgot that go map doesn't keep insertion order

Sorry for bothering you

Comment by Divjot Arora (Inactive) [ 08/May/20 ]

Hi peteladrien@gmail.com,

Thank you for the detailed report. There's a couple of things going on here and I don't think this is a driver bug:

  1. Maps in Go are unordered. The language purposely returns keys in different orders when looping over the map (e.g. using the range operator). Neither Find nor Decode are purposely messing up the map order, it's just something that Go does.
  2. Using the %v directive to print a map will print a version of the map where the keys are sorted. So if the document is {b: 1, a: 2}, it will always print as {a: 2, b: 1}. This change was introduced in Go 1.12 (https://golang.org/doc/go1.12#fmt) and can be verified without using the driver at all.

You can see that both mgo and the driver can't preserve the same key order as the original BSON document when using a tool that doesn't print out keys in sorted order by default like go-spew: https://gist.github.com/divjotarora/43bdb0bbb54f0268f72342da5e18b6e6.

Generated at Thu Feb 08 08:36:45 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.