How to use mongocompact package in mongoclient connect options

Currently I already use NewRegistryBuilder() in the mongo client options , Somehow i want to make use of NewRespectNilValuesRegistryBuilder() from mongocompact so that I can set the nilvalues in the models as empty array .

Currently I have something like below , To map the old mgo behavior

tM := reflect.TypeOf(bson.M{})
registry := bson.NewRegistryBuilder().RegisterTypeMapEntry(bsontype.EmbeddedDocument, tM).Build()
clientOpts := options.Client().ApplyURI(URI).SetAuth(info).SetRegistry(registry)
client, err := mongo.Connect(ctx, clientOpts)

Now somehow I want to incorporate and set the NewRespectNilValuesRegistryBuilder().Build() to true in the same connect options , Not sure how to do that . Also the other problem that i see is i’m not able to see the mongocompat registry file in my vendor directory

can i do something like this , SetRegistry() two times ? like below ?

tM := reflect.TypeOf(bson.M{})
registry := bson.NewRegistryBuilder().RegisterTypeMapEntry(bsontype.EmbeddedDocument, tM).Build()
clientOpts := options.Client().ApplyURI(SOMEURI).SetAuth(info).SetRegistry(registry)
//not sure if the below line is of right usage ??
clientOpts.SetRegistry(NewRespectNilValuesRegistryBuilder().Build())
client, err := mongo.Connect(ctx, clientOpts)

can anyone help me with this ?

related issue here

Hello, @karthick_d . Thanks for your question.

We definitely recommend using the mgocompat registries to mimic the encoding and decoding behavior of mgo (see docs here). If you’re trying to have nil, uninitialized Go slices Marshal to BSON empty arrays and not to BSON null, you should just use mgocompat.NewRegistryBuilder(). If you want the other features of the mgocompat registry, but you would like nil, uninitialized Go slices to Marshal to BSON null, you should use mgocompat.NewRespectNilValuesRegistryBuilder() (from your comment “nilvalues in the models as empty array”, this might not be your desired behavior).

You’ll want to call SetRegistry a single time on the ClientOptions passed to Connect. SetRegistry will change the registry used internally when we Marshal and Unmarshal values to and from BSON. Calling it multiple times on the same ClientOptions struct will simply reset the value.

Given the context of your code; I would suggest something like:

registry := mgocompat.NewRegistryBuilder().Build()
clientOpts := options.Client().ApplyURI(URI).SetAuth(info).SetRegistry(registry)
client, err := mongo.Connect(ctx, clientOpts)

I can see you’re trying to register a type map entry of EmbeddedDocument for bson.M. The mgcompat registries do that by default, so you shouldn’t need that logic.

Also the other problem that i see is i’m not able to see the mongocompat registry file in my vendor directory

I believe the vendor directory will only contain the packages that are used in your application or the packages imported by those packages. You’re likely not referring to mgocompat anywhere in your code, so it’s not vendored.

1 Like

Thanks for the workaround , this works just fine . But is it going to be an expensive operation and is it safe to do this ?

But is it going to be an expensive operation and is it safe to do this ?

While the mgocompat registries change encoding and decoding behavior, they should have more or less the same performance as the default registry. The mgocompat registry is also public, stable API within the driver, so, if by “safe” you mean stable, then yes. There should be no backward-breaking changes to their behavior in the 1.x versions of the driver.

@benjirewis Thanks for the help , Appreciate it.

In future if i want to set the empty array back to nil , will that be doable ? if yes how can I do that ?