你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
本指南介绍如何生成 Go 控制台应用程序以连接到 Azure Cosmos DB for MongoDB vCore 群集。 设置您的开发环境,使用 Azure SDK for Go 中的 azidentity
包进行身份验证,并针对数据库中的文档执行常见操作。
先决条件
- 现有的 Azure Cosmos DB for MongoDB (vCore) 群集。
Azure Cloud Shell 中最新版本的 Azure CLI。
- 如果想要在本地运行 CLI 引用命令,请使用
az login
该命令登录到 Azure CLI。
- 如果想要在本地运行 CLI 引用命令,请使用
配置控制台应用程序
接下来,创建新的控制台应用程序项目,并导入必要的库以向群集进行身份验证。
使用
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
包以与 MongoDB vCore 群集交互。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.windows.net/.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.com/", 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)) }