MongoDB Go Driver

repository·master·Indexed 27 days ago

https://github.com/mongodb/mongo-go-driver

The official Go driver for interacting with MongoDB databases. It provides support for BSON encoding, connection pooling, cursors, and network compression (snappy, zlib, zstd). The driver includes the v2 package for core functionality and experimental packages for internal driver state access.

Tokens
10K
Snippets
32
Records
77
Agent score
94%

What's inside mongodb-mongo-go-driver

  1. Use MongoDB Go Driver Experimental Packages with caution

    master

    The packages in this directory are intended for internal use and are provided to facilitate use cases requiring access to internal MongoDB driver functionality and state.

    WARNING: These packages are experimental. Their APIs may be modified or removed without notice, and there is no guarantee of backward compatibility. Use them with extreme caution.

  2. Install and use pre-commit for linting

    master

    The project uses pre-commit to lint source and text files. You can install it via Homebrew and set up the local hooks to run automatically on every commit.

    To install and initialize:

    1. Install pre-commit using Homebrew.
    2. Run pre-commit install in the repository root.

    To manually run linting checks on all files in the repository, use the --all-files flag.

    brew install pre-commit
    pre-commit install
    
    # To run manually on all files:
    pre-commit run --all-files
  3. Migrate Options usage to v2 builder pattern

    master

    In v2, the options builder pattern has changed from setting data directly on an options object to maintaining a slice of setter functions. While standard usage like options.Find().SetBatchSize(1) remains the same, you must change how you handle advanced scenarios.

    Modifying fields after building

    Instead of direct assignment, create a custom setter function and append it to the Opts slice.

    Creating a slice of options

    When using options as elements in a slice, use the options.Lister[T] type instead of a pointer to the options struct.

    Creating options from a builder

    To extract a concrete options struct from a builder, you must iterate through the Opts slice and apply each setter to a new instance of the options struct.

    // v2: Modifying fields after building
    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)
    
    // v2: Creating a slice of options
    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...)
    
    // v2: Creating options from builder
    var opts options.FindOptions
    for _, set := range options.Find().SetBatchSize(1).Opts {
      _ = set(&opts)
    }
    return findOptionAdder{option: &opts}
  4. Migrate IndexView.DropAll in 2.0

    master

    In v2, IndexView.DropAll no longer returns the server response (the number of indexes that were present). To determine how many indexes were present before dropping, you must manually list the indexes using IndexView.List before calling DropAll.

    // v2
    // List the indexes to count them
    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++
    }
    
    // Drop all indexes
    if err := coll.Indexes().DropAll(context.TODO()); err != nil {
      log.Fatalf("failed to drop indexes: %v", err)
    }
    
    // numDropped now contains the count
  5. Run Client-Side Field Level Encryption (CSE) tests

    master

    To run CSE and Queryable Encryption (QE) tests using the cse build tag without a system-wide libmongocrypt installation, follow these steps:

    1. Prerequisites: Install pkg-config and ensure DRIVERS_TOOLS points to a clone of drivers-evergreen-tools.
    2. Setup: Source the setup script to build libmongocrypt locally and export necessary environment variables: source etc/setup-cse-dev.sh
    3. Run Tests: Use the cse tag with go test.

    If you encounter ModuleNotFoundError: No module named 'boto3', delete the stale virtualenvs in $DRIVERS_TOOLS/.evergreen/ and re-source the script.

    source etc/setup-cse-dev.sh
    
    go test -tags cse ./internal/integration -run TestClientSideEncryptionProse_1_custom_key_material_test
  6. Install the MongoDB Go Driver

    master

    The recommended way to install the driver is using Go modules. You can either import the packages from go.mongodb.org/mongo-driver and let the build process handle it, or run the following command explicitly:

    go get go.mongodb.org/mongo-driver/v2/mongo

    If you are using a version of Go that does not support modules, you can use dep:

    dep ensure -add "go.mongodb.org/mongo-driver/v2/mongo"
  7. Connect to MongoDB using mongo.Client

    master

    To connect to a MongoDB instance, import the mongo package and use mongo.Connect with options.Client().ApplyURI().

    Note: mongo.Connect does not block for server discovery. To verify the connection is successful, use the Ping method with a readpref.Primary() preference.

    Always ensure you call Disconnect to clean up resources, typically using defer immediately after instantiation.

    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"
    )
    
    // Connect
    client, _ := mongo.Connect(options.Client().ApplyURI("mongodb://localhost:27017"))
    
    // Ensure disconnection
    defer func() {
        if err := client.Disconnect(ctx); err != nil {
            panic(err)
        }
    }()
    
    // Verify connection
    ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
    defer cancel()
    
    _ = client.Ping(ctx, readpref.Primary())
  8. Migrate session usage with UseSession in 2.0

    master

    In v2, client.UseSession now passes a standard context.Context to the callback instead of a mongo.SessionContext. To access the session within the callback, use mongo.SessionFromContext(ctx).

    // 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
    })