### Install libmongocrypt Locally Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/CONTRIBUTING.md Install the `libmongocrypt` library. This creates an `install` directory in the repository root. On Windows, add `c:/libmongocrypt/` to your system's PATH. ```bash task install-libmongocrypt ``` -------------------------------- ### Start Docker Server for Testing Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/CONTRIBUTING.md Use this command to start the drivers-tools server container for local testing. Ensure the DRIVERS_TOOLS environment variable is set. ```bash bash $DRIVERS_TOOLS/.evergreen/docker/start-server.sh ``` -------------------------------- ### Start Load Balancer Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/CONTRIBUTING.md Start the load balancer service. Requires MONGODB_URI to be set and the run-load-balancer.sh script to be available. ```bash MONGODB_URI='mongodb://localhost:27017,localhost:27018/' $PWD/drivers-evergreen-tools/.evergreen/run-load-balancer.sh start ``` -------------------------------- ### Install and Install Pre-commit Hooks Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/CONTRIBUTING.md Install pre-commit to automatically lint source and text files on commit. This ensures code quality and consistency. ```bash brew install pre-commit pre-commit install ``` -------------------------------- ### Source CSE Development Environment Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/CONTRIBUTING.md Source the setup script to configure the environment for Client-Side Field Level Encryption (CSE) and Queryable Encryption (QE) development tests. This script exports necessary environment variables and installs libmongocrypt. ```bash source etc/setup-cse-dev.sh ``` -------------------------------- ### Creating a Slice of Find Options (v1) Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/migration-2.0.md Example of creating a slice of FindOptions objects in v1. ```go // v1 opts1 := options.Find().SetBatchSize(1) opts2 := options.Find().SetComment("foo") opts := []*options.FindOptions{opts1, opts2} _, err := coll.Find(context.TODO(), bson.D{{"x", 1"}}, opts...) ``` -------------------------------- ### MarshalBSONValue Example Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/migration-2.0.md This example shows how to use the `MarshalBSONValue` method from the `ValueMarshaler` interface. It demonstrates retrieving the BSON type as a byte and checking if it's an array. ```go btype, _, _ := m.MarshalBSONValue() fmt.Println("type of data: %s: ", bson.Type(btype)) fmt.Println("type of data is an array: %v", bson.Type(btype) == bson.TypeArray) ``` -------------------------------- ### Create Decoder from Byte Slice (v2) Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/migration-2.0.md This is the v2 example for creating a Decoder that reads from a byte slice using bson.NewDocumentReader and bytes.NewReader. ```go // v2 b, _ := bson.Marshal(bson.M{"isOK": true}) decoder := bson.NewDecoder(bson.NewDocumentReader(bytes.NewReader(b))) ``` -------------------------------- ### Creating a Slice of Find Options (v2) Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/migration-2.0.md Example of creating a slice of options using the new Lister interface for Find operations in v2. ```go // v2 opts1 := options.Find().SetBatchSize(1) opts2 := options.Find().SetComment("foo") opts := []options.Lister[options.FindOptions]{opts1, opts2} _, err := coll.Find(context.TODO(), bson.D{{"x", 1"}}, opts...) ``` -------------------------------- ### Create Decoder from Byte Slice (v1) Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/migration-2.0.md This is the v1 example for creating a Decoder that reads from a byte slice using bsonrw.NewBSONDocumentReader. ```go // v1 b, _ := bson.Marshal(bson.M{"isOK": true}) decoder, err := bson.NewDecoder(bsonrw.NewBSONDocumentReader(b)) ``` -------------------------------- ### UnmarshalBSONValue Example Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/migration-2.0.md This example demonstrates using the `UnmarshalBSONValue` method from the `ValueUnmarshaler` interface. It shows how to unmarshal data, specifying the expected BSON type as a byte. ```go if err := m.UnmarshalBSONValue(bson.TypeEmbeddedDocument, bytes); err != nil { log.Fatalf("failed to decode embedded document: %v", err) } ``` -------------------------------- ### Encode with SetRegistry (Recommended) Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/migration-2.0.md This example demonstrates the recommended way to encode a `negatedInt` using `SetRegistry`. It involves creating an encoder and then explicitly setting the custom registry on it before encoding. ```go // v2 // Use SetRegistry buf := new(bytes.Buffer) vw := bson.NewDocumentWriter(buf) enc := bson.NewEncoder(vw) enc.SetRegistry(reg) err := enc.Encode(bson.D{{"negatedInt", negatedInt(1)}}) if err != nil { panic(err) } fmt.Println(bson.Raw(buf.Bytes()).String()) // Output: {"negatedint": {"$numberInt":"-1"}} ``` -------------------------------- ### Run Encryption Tests Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/CONTRIBUTING.md Execute the test suite for encryption, with options to include secrets handling. Requires setup tasks. ```bash task setup-env task setup-test task evg-test-versioned-api ``` -------------------------------- ### Migrate Session Usage from v1 to v2 Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/migration-2.0.md Demonstrates how to correctly use sessions in v2, extracting the session from the context instead of passing it directly. This change affects how transactions are started and operations are performed within a session. ```go // v1 client.UseSession(context.TODO(), func(sctx mongo.SessionContext) error { if err := sctx.StartTransaction(options.Transaction()); err != nil { return err } _, err = coll.InsertOne(context.TODO(), bson.D{{"x", 1}}) return err }) ``` ```go // v2 client.UseSession(context.TODO(), func(ctx context.Context) error { sess := mongo.SessionFromContext(ctx) if err := sess.StartTransaction(options.Transaction()); err != nil { return err } _, err = coll.InsertOne(context.TODO(), bson.D{{"x", 1}}) return err }) ``` -------------------------------- ### Install MongoDB Go Driver with dep Source: https://github.com/mongodb/mongo-go-driver/blob/master/README.md For versions of Go that do not support modules, use 'dep' to install the MongoDB Go Driver. This command adds the v2 mongo package. ```bash dep ensure -add "go.mongodb.org/mongo-driver/v2/mongo" ``` -------------------------------- ### Run MongoDB Orchestration for Load Balancer Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/CONTRIBUTING.md Start the MongoDB orchestration for testing with a load balancer on macOS. Requires Homebrew, drivers-evergreen-tools, and specific environment variables. ```bash LOAD_BALANCER=true TOPOLOGY=sharded_cluster AUTH=noauth SSL=nossl MONGODB_VERSION=6.0 DRIVERS_TOOLS=$PWD/drivers-evergreen-tools MONGO_ORCHESTRATION_HOME=$PWD/drivers-evergreen-tools/.evergreen/orchestration $PWD/drivers-evergreen-tools/.evergreen/run-orchestration.sh ``` -------------------------------- ### Find Operation with Multiple Options (v1) Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/migration-2.0.md Example of passing multiple options objects directly to a Find operation in v1. ```go opts1 := options.Find().SetBatchSize(1) opts2 := options.Find().SetComment("foo") _, err := coll.Find(context.TODO(), bson.D{{"x", 1"}}, opts1, opts2) if err != nil { panic(err) } ``` -------------------------------- ### BSON Decoding Behavior Change (v1) Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/migration-2.0.md This v1 example shows BSON decoding into a bson.M, where nested documents are decoded as primitive.M. ```go // v1 b1 := bson.M{"a": 1, "b": bson.M{"c": 2}} b2, _ := bson.Marshal(b1) b3 := bson.M{} bson.Unmarshal(b2, &b3) fmt.Printf("b3.b type: %T\n", b3["b"]) // Output: b3.b type: primitive.M ``` -------------------------------- ### Configure GitHub User for gh CLI Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/CONTRIBUTING.md Set your GitHub username globally for the `gh` CLI. Ensure `gh` is installed via `brew install gh`. ```bash git config --global github.user ``` -------------------------------- ### Run Basic Driver Tests Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/CONTRIBUTING.md Execute the driver's test suite against a standalone mongod instance running on localhost:27017. This command also runs linters and builds examples. ```bash task ``` -------------------------------- ### Create Encoder to Bytes Buffer (v2) Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/migration-2.0.md This is the v2 example for creating an Encoder that writes BSON values to a bytes.Buffer using bson.NewDocumentWriter. ```go // v2 buf := new(bytes.Buffer) vw := bson.NewDocumentWriter(buf) encoder := bson.NewEncoder(vw) ``` -------------------------------- ### Configure mongod for TLS and Auth Testing Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/CONTRIBUTING.md Start a mongod instance with TLS and authentication enabled for testing. Replace placeholders with actual file paths. The `--tlsAllowInvalidCertificates` flag is required for the test suite. ```bash mongod \ --auth \ --tlsMode requireTLS \ --tlsCertificateKeyFile $PATH_TO_SERVER_KEY_FILE \ --tlsCAFile $PATH_TO_CA_FILE \ --tlsAllowInvalidCertificates ``` -------------------------------- ### Install MongoDB Go Driver Source: https://github.com/mongodb/mongo-go-driver/blob/master/README.md Use Go modules to install the MongoDB Go Driver dependency in your project. This command adds the v2 mongo package. ```bash go get go.mongodb.org/mongo-driver/v2/mongo ``` -------------------------------- ### Create Encoder to Bytes Buffer (v1) Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/migration-2.0.md This is the v1 example for creating an Encoder that writes BSON values to a bytes.Buffer using bsonrw.NewBSONValueWriter. ```go // v1 buf := new(bytes.Buffer) vw, err := bsonrw.NewBSONValueWriter(buf) encoder, err := bson.NewEncoder(vw) ``` -------------------------------- ### Configure ObjectIDAsHex for BSON Decoding Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/migration-2.0.md v2 simplifies BSON decoding configuration by removing the need for explicit CodecOptions and Registry setup. Use the `ObjectIDAsHexString()` method on the decoder directly. ```go // v1 var res struct { ID string } codecOpt := bsonoptions.StringCodec().SetDecodeObjectIDAsHex(true) strCodec := bsoncodec.NewStringCodec(codecOpt) reg := bson.NewRegistryBuilder().RegisterDefaultDecoder(reflect.String, strCodec).Build() dc := bsoncodec.DecodeContext{Registry: reg} dec, err := bson.NewDecoderWithContext(dc, bsonrw.NewBSONDocumentReader(DOCUMENT)) if err != nil { panic(err) } err = dec.Decode(&res) if err != nil { panic(err) } ``` ```go // v2 var res struct { ID string } decoder := bson.NewDecoder(bson.NewDocumentReader(bytes.NewReader(DOCUMENT))) decoder.ObjectIDAsHexString() err := decoder.Decode(&res) if err != nil { panic(err) } ``` -------------------------------- ### BSON Decoding Behavior Change (v2) Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/migration-2.0.md This v2 example shows BSON decoding into a bson.D by default, where nested documents are decoded as bson.D. ```go // v2 b1 := bson.M{"a": 1, "b": bson.M{"c": 2}} b2, _ := bson.Marshal(b1) b3 := bson.M{} bson.Unmarshal(b2, &b3) fmt.Printf("b3.b type: %T\n", b3["b"]) // Output: b3.b type: bson.D ``` -------------------------------- ### Run Go Driver Tests in Docker Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/CONTRIBUTING.md Execute the Go Driver tests within a Docker container. This script handles the necessary setup for testing. It accepts an optional TASKFILE_TARGET argument. ```bash make run-docker ``` -------------------------------- ### Encode with MarshalWithRegistry Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/migration-2.0.md This example demonstrates encoding a `negatedInt` using `MarshalWithRegistry` with a custom registry. This method is used when you need to apply custom encoding logic defined in a registry. ```go // v1 // Use MarshalWithRegistry b, err := bson.MarshalWithRegistry(reg, bson.D{{"negatedInt", negatedInt(1)}}) if err != nil { panic(err) } fmt.Println(bson.Raw(b).String()) // Output: {"negatedint": {"$numberInt":"-1"}} ``` -------------------------------- ### Test Replica Set Topology Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/CONTRIBUTING.md Run tests against a local replica set by setting the MONGODB_URI environment variable. This example configures a replica set named 'rs1' with three nodes. ```bash MONGODB_URI="mongodb://localhost:27017,localhost:27018,localhost:27019/?replicaSet=rs1" make ``` -------------------------------- ### Get Distinct Values (v1) Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/migration-2.0.md Use this version to retrieve distinct values and manually append them to a slice. ```go // v1 filter := bson.D{{"age", bson.D{{"$gt", 25}}}} values, err := coll.Distinct(context.TODO(), "name", filter) if err != nil { log.Fatalf("failed to get distinct values: %v", err) } people := make([]any, 0, len(values)) for _, value := range values { people = append(people, value) } fmt.Printf("car-renting persons: %v\n", people) ``` -------------------------------- ### Encode with NewEncoderWithContext (Deprecated) Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/migration-2.0.md This example shows encoding a `negatedInt` using `NewEncoderWithContext` and a custom registry. Note that `NewEncoderWithContext` has been removed in favor of `SetRegistry` in newer versions. ```go // v1 // Use NewEncoderWithContext buf := new(bytes.Buffer) vw, err := bsonrw.NewBSONValueWriter(buf) if err != nil { panic(err) } ec := bsoncodec.EncodeContext{Registry: reg} enc, err := bson.NewEncoderWithContext(ec, vw) if err != nil { panic(err) } err = enc.Encode(bson.D{{"negatedInt", negatedInt(1)}}) if err != nil { panic(err) } fmt.Println(bson.Raw(buf.Bytes()).String()) // Output: {"negatedint": {"$numberInt":"-1"}} ``` -------------------------------- ### Get Raw Distinct Values with Options (v2) Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/migration-2.0.md This version retrieves distinct values as raw data, allowing iteration and type conversion. It also demonstrates setting options like MaxTime. ```go // v2 filter := bson.D{{"age", bson.D{{"$gt", 25}}}} distinctOpts := options.Distinct().SetMaxTime(2 * time.Second) res := coll.Distinct(context.TODO(), "name", filter, distinctOpts) if err := res.Err(); err != nil { log.Fatalf("failed to get distinct result: %v", err) } rawArr, err := res.Raw() if err != nil { log.Fatalf("failed to get raw data: %v", err) } values, err := rawArr.Values() if err != nil { log.Fatalf("failed to get values: %v", err) } people := make([]string, 0, len(rawArr)) for _, value := range values { people = append(people, value.String()) } fmt.Printf("car-renting persons: %v\n", people) ``` -------------------------------- ### Decode BSON Integer as Lenient Boolean using NewDecoderWithContext (v1) Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/migration-2.0.md Illustrates decoding a BSON document with a non-zero integer into a lenientBool field using the deprecated NewDecoderWithContext. This example highlights the previous method for custom decoding with a registry. ```go // v1 // Use NewDecoderWithContext // Marshal a BSON document with a single field "isOK" that is a non-zero // integer value. b, err := bson.Marshal(bson.M{"isOK": 1}) if err != nil { panic(err) } // Now try to decode the BSON document to a struct with a field "IsOK" that // is type lenientBool. Expect that the non-zero integer value is decoded // as boolean true. type MyDocument struct { IsOK lenientBool `bson:"isOK"` } var doc MyDocument dc := bsoncodec.DecodeContext{Registry: reg} dec, err := bson.NewDecoderWithContext(dc, bsonrw.NewBSONDocumentReader(b)) if err != nil { panic(err) } err = dec.Decode(&doc) if err != nil { panic(err) } fmt.Printf("%+v\n", doc) // Output: {IsOK:true} ``` -------------------------------- ### Run Specific Docker Test Task Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/CONTRIBUTING.md Run a specific test task within the Docker environment, for example, testing against a sharded cluster with enterprise authentication. Ensure the server was started with the appropriate topology. ```bash TOPOLOGY=sharded_cluster task run-docker -- evg-test-enterprise-auth ``` -------------------------------- ### Creating Find Options from Builder (v1) Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/migration-2.0.md Illustrates creating a FindOptions object and then setting a field in v1. ```go // v1 opt := &options.FindOptions{} opt.SetBatchSize(1) return findOptionAdder{option: opt} ``` -------------------------------- ### Enable Network Compression via Client Options Source: https://github.com/mongodb/mongo-go-driver/blob/master/README.md Alternatively, enable network compression by using ClientOptions.SetCompressors. The driver negotiates the first common compressor. ```go opts := options.Client().SetCompressors([]string{"snappy", "zlib", "zstd"}) client, _ := mongo.Connect(opts) ``` -------------------------------- ### Creating Find Options from Builder (v2) Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/migration-2.0.md Shows how to create a FindOptions object by applying setters from a builder in v2. ```go // v2 var opts options.FindOptions for _, set := range options.Find().SetBatchSize(1).Opts { _ = set(&opts) } return findOptionAdder{option: &opts} ``` -------------------------------- ### Connect to MongoDB Source: https://github.com/mongodb/mongo-go-driver/blob/master/README.md Import the mongo package and create a mongo.Client with the Connect function. Ensure to defer a call to Disconnect. ```go import ( "context" "time" "go.mongodb.org/mongo-driver/v2/mongo" "go.mongodb.org/mongo-driver/v2/mongo/options" "go.mongodb.org/mongo-driver/v2/mongo/readpref" ) client, _ := mongo.Connect(options.Client().ApplyURI("mongodb://localhost:27017")) ``` ```go defer func() { if err := client.Disconnect(ctx); err != nil { panic(err) } }() ``` -------------------------------- ### Enable Network Compression via Connection String Source: https://github.com/mongodb/mongo-go-driver/blob/master/README.md Enable network compression by specifying the 'compressors' parameter in the connection URI. The driver negotiates the first common compressor. ```go opts := options.Client().ApplyURI("mongodb://localhost:27017/?compressors=snappy,zlib,zstd") client, _ := mongo.Connect(opts) ``` -------------------------------- ### Test Wire Protocol Compression Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/CONTRIBUTING.md Run tests with wire protocol compression enabled by setting the `MONGO_GO_DRIVER_COMPRESSOR` environment variable. Supported values are `snappy`, `zlib`, or `zstd`. Ensure mongod/mongos includes `zlib` if testing zLib compression. ```bash MONGO_GO_DRIVER_COMPRESSOR=snappy make ``` -------------------------------- ### Connecting to MongoDB with NewClient vs Connect Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/migration-2.0.md mongo.NewClient has been removed. Use the mongo.Connect function instead for establishing a client connection. ```go client, err := mongo.NewClient(options.Client()) if err != nil { log.Fatalf("failed to create client: %v", err) } if err := client.Connect(context.TODO()); err != nil { log.Fatalf("failed to connect to server: %v", err) } ``` ```go client, err := mongo.Connect(options.Client()) if err != nil { log.Fatalf("failed to connect to server: %v", err) } ``` -------------------------------- ### Create GridFS Bucket (v1) Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/migration-2.0.md This version uses the `gridfs.NewBucket` function from the `gridfs` package. ```go // v1 var bucket gridfs.Bucket bucket, _ = gridfs.NewBucket(db, opts) ``` -------------------------------- ### Merge Options Logic (Pseudocode) Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/migration-2.0.md Illustrates the general logic for merging options where later options override earlier ones. ```pseudo function MergeOptions(target, optionsList): for each options in optionsList: if options is null or undefined: continue for each key, value in options: if value is not null or undefined: target[key] = value return target ``` -------------------------------- ### Task commands Source: https://github.com/mongodb/mongo-go-driver/blob/master/AGENTS.md Common commands for building, testing, and linting the Go driver using Task. ```bash task # default: build + check-license + check-fmt + check-modules + lint + test-short task fmt # gofumpt -w . — use this, not plain gofmt task build # includes compilecheck-119 (Go 1.19 compat) task lint # golangci-lint across linux/{386,arm,arm64,amd64,ppc64le,s390x} task test-short # race detector, ~60s timeout — fast feedback task test # full suite, serial (-p 1), 1800s timeout, requires mongod task api-report # required when public API changes — include output in PR description ``` -------------------------------- ### Run Tests with Auth and TLS Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/CONTRIBUTING.md Execute the test suite with authentication and TLS enabled. Set the necessary environment variables for CA file, key files, and the MongoDB URI. The `authSource` must be set to `admin`. ```bash AUTH=auth SSL=ssl \ MONGO_GO_DRIVER_CA_FILE=$PATH_TO_CA_FILE \ MONGO_GO_DRIVER_KEY_FILE=$PATH_TO_CLIENT_KEY_FILE \ MONGO_GO_DRIVER_PKCS8_ENCRYPTED_KEY_FILE=$PATH_TO_ENCRYPTED_KEY_FILE \ MONGO_GO_DRIVER_PKCS8_UNENCRYPTED_KEY_FILE=$PATH_TO_UNENCRYPTED_KEY_FILE \ MONGODB_URI="mongodb://user:password@localhost:27017/?authSource=admin" \ make ``` -------------------------------- ### Insert Document Source: https://github.com/mongodb/mongo-go-driver/blob/master/README.md Retrieve a Database and Collection instance from the Client, then use the Collection instance to insert documents. Requires bson.D for document structure. ```go collection := client.Database("testing").Collection("numbers") ``` ```go ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defuncel() res, _ := collection.InsertOne(ctx, bson.D{{"name", "pi"}, {"value", 3.14159}}) id := res.InsertedID ``` -------------------------------- ### Create GridFS Bucket (v2) Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/migration-2.0.md This version uses the `db.GridFSBucket` method from the merged `mongo` package. ```go // v2 var bucket mongo.GridFSBucket bucket, _ = db.GridFSBucket(opts) ``` -------------------------------- ### Run Load Balancer Tests Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/CONTRIBUTING.md Execute the load balancer tests using the Taskfile. Alternatively, the docker runner can be used with the 'evg-test-load-balancers' target. ```bash task evg-test-load-balancers ``` -------------------------------- ### Insert Documents (v2) Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/migration-2.0.md This version simplifies insertion by accepting a slice of any type directly, eliminating the need for manual conversion to `[]any`. ```go // v2 books := []book{ { Name: "Don Quixote de la Mancha", Author: "Miguel de Cervantes", }, { Name: "Cien años de soledad", Author: "Gabriel García Márquez", }, { Name: "Crónica de una muerte anunciada", Author: "Gabriel García Márquez", }, } ``` -------------------------------- ### Run CSE Integration Test Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/CONTRIBUTING.md Execute a specific integration test for Client-Side Encryption (CSE) using the 'cse' build tag. Ensure the development environment is sourced. ```go go test -tags cse ./internal/integration -run TestClientSideEncryptionProse_1_custom_key_material_test ``` -------------------------------- ### Modifying Find Options After Building (v2) Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/migration-2.0.md Shows how to modify options after building in v2 by appending a custom setter function to the Opts slice. ```go // v2 opts := options.Find().SetBatchSize(1) maxAwaitTimeSetter := func(opts *options.FindOptions) error { if opts.MaxAwaitTime == nil { opts.MaxAwaitTime = &defaultMaxAwaitTime } return nil } opts.Opts = append(opts.Opts, maxAwaitTimeSetter) ``` -------------------------------- ### Insert Documents (v1) Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/migration-2.0.md This version requires documents to be explicitly converted to an `[]any` slice before insertion. ```go // v1 books := []book{ { Name: "Don Quixote de la Mancha", Author: "Miguel de Cervantes", }, { Name: "Cien años de soledad", Author: "Gabriel García Márquez", }, { Name: "Crónica de una muerte anunciada", Author: "Gabriel García Márquez", }, } booksi := make([]any, len(books)) for i, book := range books { booksi[i] = book } _, err = collection.InsertMany(ctx, booksi) if err != nil { log.Fatalf("could not insert Spanish authors: %v", err) } ``` -------------------------------- ### Migrate Collection Cloning from v1 to v2 Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/migration-2.0.md Shows the change in the collection cloning method signature. In v2, `collection.Clone` no longer returns an error. ```go // v1 clonedColl, err := coll.Clone(options.Collection()) if err != nil { log.Fatalf("failed to clone collection: %v", err) } ``` ```go // v2 clonedColl := coll.Clone(options.Collection()) ``` -------------------------------- ### Handling MongoDB Sessions: Slice of mongo.Session vs Slice of *mongo.Session Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/migration-2.0.md The StartSession method now returns a pointer to a mongo.Session struct (*mongo.Session) instead of a mongo.Session value. Update collections that store sessions accordingly. ```go // v1 var sessions []mongo.Session for i := 0; i < numSessions; i++ { sess, _ := client.StartSession() sessions = append(sessions, sess) } ``` ```go // v2 var sessions []*mongo.Session for i := 0; i < numSessions; i++ { sess, _ := client.StartSession() sessions = append(sessions, sess) } ``` -------------------------------- ### Manually Run Pre-commit Checks Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/CONTRIBUTING.md Manually run all pre-commit checks across all files in the repository. This is useful for verifying linting compliance before committing. ```bash pre-commit run --all-files ``` -------------------------------- ### Configure Client for DefaultDocumentMap Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/migration-2.0.md Configures the client options to set DefaultDocumentMap to true, ensuring all documents are decoded into map[string]any by default. ```go clientOpts := options.Client(). SetBSONOptions(&options.BSONOptions{ DefaultDocumentMap: true, }) ``` -------------------------------- ### List Collection Specifications (v1) Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/migration-2.0.md This version returns a slice of pointers to `mongo.CollectionSpecification`. ```go // v1 var specs []*mongo.CollectionSpecification specs, _ = db.ListCollectionSpecifications(context.TODO(), bson.D{}) ``` -------------------------------- ### Modifying Find Options After Building (v1) Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/migration-2.0.md Demonstrates modifying an option field directly after the options object has been built in v1. ```go // v1 opts := options.Find().SetBatchSize(1) if opts.MaxAwaitTime == nil { opts.MaxAwaitTime = &defaultMaxAwaitTime } ``` -------------------------------- ### Cherry-pick PR with GitHub App Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/CONTRIBUTING.md Use this comment within a Pull Request to trigger the backporting process to a specified target branch. ```bash drivers-pr-bot please backport to {target_branch} ``` -------------------------------- ### Decode Documents into map[string]any Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/migration-2.0.md Configures the decoder to always decode documents into map[string]any instead of bson.M, using Decoder.DefaultDocumentMap(). ```go b1 := map[string]any{"a": 1, "b": map[string]any{"c": 2}} b2, _ := bson.Marshal(b1) decoder := bson.NewDecoder(bson.NewDocumentReader(bytes.NewReader(b2))) decoder.DefaultDocumentMap() var b3 map[string]any decoder.Decode(&b3) fmt.Printf("b3.b type: %T\n", b3["b"]) // Output: b3.b type: map[string]interface {} ``` -------------------------------- ### Build and Invoke AWS Lambda Function Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/CONTRIBUTING.md Build the AWS Lambda image and invoke the MongoDBFunction lambda function. Ensure MONGODB_URI is exported. ```bash MONGODB_URI="mongodb://host.docker.internal:27017" task build-faas-awslambda ``` -------------------------------- ### Decode BSON Integer as Lenient Boolean using SetRegistry (v2) Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/migration-2.0.md Shows the current recommended method for decoding a BSON document with a non-zero integer into a lenientBool field using SetRegistry on a decoder. This is the modern approach replacing older methods. ```go // v2 // Use SetRegistry // Marshal a BSON document with a single field "isOK" that is a non-zero // integer value. b, err := bson.Marshal(bson.M{"isOK": 1}) if err != nil { panic(err) } // Now try to decode the BSON document to a struct with a field "IsOK" that // is type lenientBool. Expect that the non-zero integer value is decoded // as boolean true. type MyDocument struct { IsOK lenientBool `bson:"isOK"` } var doc MyDocument dec := bson.NewDecoder(bson.NewDocumentReader(bytes.NewReader(b))) dec.SetRegistry(reg) err = dec.Decode(&doc) if err != nil { panic(err) } fmt.Printf("%+v\n", doc) // Output: {IsOK:true} ``` -------------------------------- ### Query Documents with Cursor Source: https://github.com/mongodb/mongo-go-driver/blob/master/README.md Methods returning multiple documents yield a cursor. Iterate through the cursor to process results and handle potential errors. ```go ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defuncel() cur, err := collection.Find(ctx, bson.D{}) if err != nil { log.Fatal(err) } defer cur.Close(ctx) for cur.Next(ctx) { var result bson.D if err := cur.Decode(&result); err != nil { log.Fatal(err) } // do something with result.... } if err := cur.Err(); err != nil { log.Fatal(err) } ``` -------------------------------- ### List Collection Specifications (v2) Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/migration-2.0.md This version returns a slice of `mongo.CollectionSpecification` structs directly. ```go // v2 var specs []mongo.CollectionSpecification specs, _ = db.ListCollectionSpecifications(context.TODO(), bson.D{}) ``` -------------------------------- ### Print Extended JSON Representation of bson.D Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/migration-2.0.md Demonstrates how bson.D implements json.Marshaler and its String() method returns an Extended JSON representation. ```go // v2 d := D{{"a", 1}, {"b", 2}} fmt.Printf("%s\n", d) // Output: {"a":{"$numberInt":"1"},"b":{"$numberInt":"2"}} ``` -------------------------------- ### GridFS Write Deadline Handling Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/migration-2.0.md SetWriteDeadline methods have been removed from GridFS operations. Use context.Context for managing deadlines instead. ```go // v1 uploadStream, _ := bucket.OpenUploadStream("filename", uploadOpts) uploadStream.SetWriteDeadline(time.Now().Add(2*time.Second)) ``` ```go // v2 ctx, cancel := context.WithTimeout(context.TODO(), 2*time.Second) deferr cancel() uploadStream, _ := bucket.OpenUploadStream(ctx, "filename", uploadOpts) ``` -------------------------------- ### Update Imports for BSON Source: https://github.com/mongodb/mongo-go-driver/blob/master/README.md If using bson.D, ensure the bson package is included in your import statements. ```go import ( "context" "log" "time" "go.mongodb.org/mongo-driver/v2/bson" "go.mongodb.org/mongo-driver/v2/mongo" "go.mongodb.org/mongo-driver/v2/mongo/options" "go.mongodb.org/mongo-driver/v2/mongo/readpref" ) ``` -------------------------------- ### DropAll Indexes Response Handling Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/migration-2.0.md The server response for DropAll has been simplified. In v1, the response was unmarshaled to determine the number of indexes dropped. In v2, the number of dropped indexes is determined by listing indexes before and after the drop operation. ```go // v1 res, err := coll.Indexes().DropAll(context.TODO()) if err != nil { log.Fatalf("failed to drop indexes: %v", err) } type dropResult struct { NIndexesWas int } dres := dropResult{} if err := bson.Unmarshal(res, &dres); err != nil { log.Fatalf("failed to decode: %v", err) } numDropped := dres.NIndexWas // Use numDropped ``` ```go // v2 // List the indexes cur, err := coll.Indexes().List(context.TODO()) if err != nil { log.Fatalf("failed to list indexes: %v", err) } numDropped := 0 for cur.Next(context.TODO()) { numDropped++ } if err := coll.Indexes().DropAll(context.TODO()); err != nil { log.Fatalf("failed to drop indexes: %v", err) } // List the indexes cur, err = coll.Indexes().List(context.TODO()) if err != nil { log.Fatalf("failed to list indexes: %v", err) } // Use numDropped ``` -------------------------------- ### Upgrade MongoDB Go Driver using mod Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/migration-2.0.md Use the 'mod upgrade' command to update the MongoDB Go Driver import path from v1 to v2. ```bash mod upgrade --mod-name=go.mongodb.org/mongo-driver ``` -------------------------------- ### Enable Decoding BSON ObjectId as Hex String in Go Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/migration-2.0.md Demonstrates how to use the ObjectIDAsHexString method on a decoder to enable the decoding of BSON ObjectIds as hexadecimal strings. By default, ObjectIds are not decoded as strings. ```go // Decoder.ObjectIDAsHexString() // This method enables decoding a BSON ObjectId as a hexadecimal string. // Otherwise, the decoder returns an error by default instead of decoding as the UTF-8 representation of the raw ObjectId bytes, which results in a garbled and unusable string. ``` -------------------------------- ### Run Taskfile Targets for Validation Source: https://github.com/mongodb/mongo-go-driver/blob/master/docs/CONTRIBUTING.md Execute these Taskfile targets to ensure your code compiles, passes linting, and all tests are successful before submitting a pull request. ```bash task fmt task lint task test task test-race ```