本指南介绍如何生成 Go 控制台应用程序以连接到 Azure DocumentDB 群集。 设置您的开发环境,使用 Azure SDK for Go 中的 azidentity 包进行身份验证,并针对数据库中的文档执行常见操作。
先决条件
Azure 订阅服务
- 如果没有 Azure 订阅,请创建 试用版
现有的 Azure DocumentDB 群集
- 如果没有群集,请 创建新群集
如需在本地运行 CLI 参考命令,请安装 Azure CLI。 如果在 Windows 或 macOS 上运行,请考虑在 Docker 容器中运行 Azure CLI。 有关详细信息,请参阅如何在 Docker 容器中运行 Azure CLI。
如果使用的是本地安装,请使用 az login 命令登录到 Azure CLI。 若要完成身份验证过程,请遵循终端中显示的步骤。 有关其他登录选项,请参阅使用 Azure CLI 登录。
出现提示时,请在首次使用时安装 Azure CLI 扩展。 有关扩展的详细信息,请参阅 将扩展与 Azure CLI 配合使用。
运行az version命令,以查看已安装的版本和依赖库。 若要升级到最新版本,请运行az upgrade。
配置控制台应用程序
接下来,创建新的控制台应用程序项目,并导入必要的库以向群集进行身份验证。
使用
go mod init命令为项目创建新的 Go 模块。go mod init cosmicworks安装
azidentity包来管理 Microsoft Entra ID 的身份验证。go get -u github.com/Azure/azure-sdk-for-go/sdk/azidentity安装
mongo包以与群集交互。go get -u go.mongodb.org/mongo-driver/v2/mongo在项目目录中创建一
main.go个名为的新文件。touch main.go
连接至群集
现在,使用 Azure.Identity 库获取一个 TokenCredential,以用于连接到您的群集。 官方 MongoDB 驱动程序具有一个特殊接口,必须实现该接口,以便从 Microsoft Entra 获取令牌,以便在连接到群集时使用。
首先,在
main.go文件的顶部导入所需的包。import ( "context" "crypto/tls" "encoding/json" "fmt" "time" "github.com/Azure/azure-sdk-for-go/sdk/azcore/policy" "github.com/Azure/azure-sdk-for-go/sdk/azidentity" "go.mongodb.org/mongo-driver/v2/bson" "go.mongodb.org/mongo-driver/v2/mongo" "go.mongodb.org/mongo-driver/v2/mongo/options" )创建贯穿整个应用的上下文环境。
ctx := context.Background()创建一个实例,该实例
DefaultAzureCredential用于使用 Microsoft Entra ID 进行身份验证。credential, err := azidentity.NewDefaultAzureCredential(nil) if err != nil { panic(err) }创建在 MongoDB 驱动程序需要进行身份验证时获取访问令牌的回调函数。
azureIdentityTokenCallback := func(_ context.Context, _ *options.OIDCArgs) (*options.OIDCCredential, error) { accessToken, err := credential.GetToken(ctx, policy.TokenRequestOptions{ Scopes: []string{"https://ossrdbms-aad.database.chinacloudapi.cn/.default"}, }) if err != nil { return nil, err } return &options.OIDCCredential{ AccessToken: accessToken.Token, }, nil }设置群集名称并构造连接 URI。
clusterName := "<azure-cosmos-db-mongodb-vcore-cluster-name>" uri := fmt.Sprintf("mongodb+srv://%s.global.mongocluster.cosmos.azure.cn/", clusterName)配置 MongoDB 客户端的身份验证凭据。
auth := options.Credential{ AuthMechanism: "MONGODB-OIDC", OIDCMachineCallback: azureIdentityTokenCallback, }使用连接参数、传输层安全性(TLS)配置和身份验证设置客户端选项。
clientOptions := options.Client(). ApplyURI(uri). SetConnectTimeout(2 * time.Minute). SetRetryWrites(true). SetTLSConfig(&tls.Config{}). SetAuth(auth)使用配置的选项创建 MongoDB 客户端实例。
client, err := mongo.Connect(clientOptions) if err != nil { panic(err) } fmt.Println("Client created")添加一个 defer 语句,以确保应用程序退出时客户端正确断开连接。
defer func() { if err = client.Disconnect(ctx); err != nil { panic(err) } }()
执行常见操作
最后,使用官方库对数据库、集合和文档执行常见任务。 在这里,你将使用相同的类和方法与 MongoDB 或 DocumentDB 进行交互来管理集合和项。
按名称获取对数据库的引用。
database := client.Database("<database-name>") fmt.Println("Database pointer created")获取对数据库中集合的引用。
collection := database.Collection("<collection-name>") fmt.Println("Collection pointer created")定义产品结构来表示文档结构。
type Product struct { ID string `bson:"_id"` Category string `bson:"category"` Name string `bson:"name"` Quantity int `bson:"quantity"` Price decimal128.Decimal128 `bson:"price"` Clearance bool `bson:"clearance"` }使用已配置为
collection.ReplaceOne的 操作来创建或更新文档。opts := options.Replace().SetUpsert(true) upsertFilter := bson.D{{Key: "_id", Value: "aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb"}} priceDecimal, err := bson.ParseDecimal128("850.00") if err != nil { panic(err) } document := Product{ ID: "aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb", Category: "gear-surf-surfboards", Name: "Yamba Surfboard", Quantity: 12, Price: priceDecimal, Clearance: false} result, err := collection.ReplaceOne(ctx, upsertFilter, document, opts) if err != nil { panic(err) } fmt.Printf("Documents upserted count:\t%d\n", result.UpsertedCount)使用
collection.FindOne并结合_id和category的筛选来读取特定文档。readFilter := bson.D{{Key: "_id", Value: "aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb"}, {Key: "category", Value: "gear-surf-surfboards"}} var target Product err = collection.FindOne(ctx, readFilter).Decode(&target) if err != nil { panic(err) } fmt.Printf("Read document name:\t%s\n", target.Name)查询与特定
category匹配的多个文档,使用collection.Find。queryFilter := bson.D{{Key: "category", Value: "gear-surf-surfboards"}} cursor, err := collection.Find(ctx, queryFilter) if err != nil { panic(err) }从游标中检索所有匹配的文档。
var products []Product if err = cursor.All(ctx, &products); err != nil { panic(err) }遍历并显示查询中找到的所有产品。
for _, product := range products { json, err := json.Marshal(product) if err != nil { panic(err) } fmt.Printf("Found document:\t%s\n", string(json)) }