更新时间:2024-01-18 GMT+08:00

完整示例

注意事项

  1. 业务的Context超时时间建议设置不低于10秒。
  2. 同时在以下业务场景下,一定要配置MaxTimeMS:
    • Find
    • FindAndModify
    • DropIndexes
    • Distinct
    • Aggregate
    • CreateIndexes
    • Count

代码示例

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() {

    // 高可用连接串
    // 认证用的用户名和密码直接写到代码中有很大的安全风险,建议在配置文件或者环境变量中存放(密码应密文存放、使用时解密),确保安全;
    // 本示例以用户名和密码保存在环境变量中为例,运行本示例前请先在本地环境中设置环境变量(环境变量名称请根据自身情况进行设置)EXAMPLE_USERNAME_ENV和EXAMPLE_PASSWORD_ENV。
    username = System.getenv("EXAMPLE_USERNAME_ENV")
    password = System.getenv("EXAMPLE_PASSWORD_ENV")
    highProxyUri := fmt.Sprintf("mongodb://%v:%v@host1:8635,host2:8635/?
    authSource=admin&replicaSet=replica&readPreference=secondaryPreferred",username,password)
    clientOpts := options.Client().ApplyURI(highProxyUri)
    clientOpts.SetConnectTimeout(ConnectTimeout)
    clientOpts.SetSocketTimeout(SocketTimeout)
    clientOpts.SetMaxConnIdleTime(MaxIdleTime)
    clientOpts.SetMaxPoolSize(MaxPoolSize)
    clientOpts.SetMinPoolSize(MinPoolSize)

    // 连接数据库
    ConnectCtx, cancel := context.WithTimeout(context.Background(), ConnectTimeout)
    defer cancel()
    client, err := mongo.Connect(ConnectCtx, clientOpts)
    if err != nil {
        fmt.Println("mongo实例连接失败:", err)
        return
    }
    // Ping 主节点
    ctx, cancel := context.WithTimeout(context.Background(), DefaultContextTimeOut)
    defer cancel()
    err = client.Ping(ctx, readpref.Primary())
    if err != nil {
        fmt.Println("ping 主节点失败:", err)
        return
    }
    // 选择数据库和集合
    collection := client.Database("test").Collection("numbers")
    // 插入单条数据
    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("插入单条记录失败:", err)
        return
    } else {
        fmt.Println(oneRes)
    }
    // 批量插入
    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("批量插入失败:", err)
        return
    } else {
        fmt.Println(manyRes)
    }
    db := client.Database("test")
    // 分页查询
    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("分页查询失败:", err)
        return
    }
    for cursor.Next(ctx) {
        fmt.Println(cursor.Current)
    }
}