Updated on 2023-10-08 GMT+08:00

Complete Example

Precautions

  1. It is recommended that the context timeout interval be set to a value no less than 10 seconds.
  2. MaxTimeMS must be set in the following business scenarios:
    • Find
    • FindAndModify
    • DropIndexes
    • Distinct
    • Aggregate
    • CreateIndexes
    • Count

Sample Code

import (
    "context"
    "fmt"
    "strconv"
    "time"

    "go.mongodb.org/mongo-driver/bson"
    "go.mongodb.org/mongo-driver/mongo"
    "go.mongodb.org/mongo-driver/mongo/options"
    "go.mongodb.org/mongo-driver/mongo/readpref"
)

const (
    ConnectTimeout        = 10 * time.Second
    SocketTimeout         = 60 * time.Second
    MaxIdleTime           = 10 * time.Second
    MaxPoolSize           = 100
    MinPoolSize           = 10
    DefaultContextTimeOut = 10 * time.Second
    MaxTimeMS             = 10 * time.Second
)

func main() {

    // HA connection string
    highProxyUri := "mongodb://rwuser:your_password@host1:8635,host2:8635/?authSource=admin&replicaSet=replica&readPreference=secondaryPreferred"
    clientOpts := options.Client().ApplyURI(highProxyUri)
    clientOpts.SetConnectTimeout(ConnectTimeout)
    clientOpts.SetSocketTimeout(SocketTimeout)
    clientOpts.SetMaxConnIdleTime(MaxIdleTime)
    clientOpts.SetMaxPoolSize(MaxPoolSize)
    clientOpts.SetMinPoolSize(MinPoolSize)

    // Connect to a database.
    ConnectCtx, cancel := context.WithTimeout(context.Background(), ConnectTimeout)
    defer cancel()
    client, err := mongo.Connect(ConnectCtx, clientOpts)
    if err != nil {
       fmt.Println("Failed to connect to the mongo instance:", err)
        return
    }
    //Ping the primary node.
    ctx, cancel := context.WithTimeout(context.Background(), DefaultContextTimeOut)
    defer cancel()
    err = client.Ping(ctx, readpref.Primary())
    if err != nil {
        fmt.Println("Failed to ping the primary node:", err)
        return
    }
    //Select the database and collection.
    collection := client.Database("test").Collection("numbers")
    //Insert a data record.
    ctx, cancel = context.WithTimeout(context.Background(), DefaultContextTimeOut)
    defer cancel()
    oneRes, err := collection.InsertOne(ctx, bson.D{{"name", "e"}, {"value", 2.718}})
    if err != nil {
       fmt.Println("Failed to insert a data record:", err)
        return
    } else {
        fmt.Println(oneRes)
    }
    // Batch insert.
    ctx, cancel = context.WithTimeout(context.Background(), DefaultContextTimeOut)
    defer cancel()
    docs := make([]interface{}, 100)
    for i := 0; i < 100; i++ {
        docs[i] = bson.D{{"name", "name" + strconv.Itoa(i)}, {"value", i}}
    }
    manyRes, err := collection.InsertMany(ctx, docs)
    if err != nil {
       fmt.Println("Batch insertion failed:", err)
        return
    } else {
        fmt.Println(manyRes)
    }
    db := client.Database("test")
    // Query data by page.
    ctx, cancel = context.WithTimeout(context.Background(), DefaultContextTimeOut)
    defer cancel()
    cursor, err := db.Collection("numbers").Find(ctx, struct{}{}, options.Find().SetBatchSize(100).SetMaxTime(MaxTimeMS).SetSkip(int64(1000)).SetLimit(100))
    if err != nil {
        fmt.Println("Pagination query failed:", err)
        return
    }
    for cursor.Next(ctx) {
        fmt.Println(cursor.Current)
    }
}