共用方式為


使用 Azure DocumentDB 建立 Go 控制台應用程式

本指南說明如何建置一個 Go 主控台應用程式,以連接 Azure DocumentDB 叢集。 您已設定開發環境、使用 azidentity 適用於 Go 的 Azure SDK 套件進行驗證,並在資料庫中的檔案上執行一般作業。

先決條件

  • Azure 訂用帳戶

    • 如果您沒有 Azure 訂用帳戶,請建立 免費帳戶
  • 一個現有的 Azure DocumentDB 叢集

  • 為叢集設定 Microsoft Entra 驗證,且您的身分識別已獲授與 root 角色。

  • 最新版本的 Go

設定主控台應用程式

接下來,建立新的主控台應用程式專案,並匯入必要的函式庫來驗證您的叢集。

  1. 使用 go mod init 命令為您的專案建立新的 Go 模組。

    go mod init cosmicworks
    
  2. 安裝azidentity套件來處理Microsoft Entra ID的身份驗證。

    go get -u github.com/Azure/azure-sdk-for-go/sdk/azidentity
    
  3. 安裝套件 mongo ,與你的叢集互動。

    go get -u  go.mongodb.org/mongo-driver/v2/mongo
    
  4. 在項目目錄中建立名為 main.go 的新檔案。

    touch main.go
    

連接至叢集

現在,使用 Azure.Identity 庫取得 TokenCredential,以用來連線到您的叢集。 官方 MongoDB 驅動程式有一個特殊的介面,必須實作才能從 Microsoft Entra 取得令牌,以在連線到叢集時使用。

  1. 首先,在 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"
    )
    
  2. 建立在整個應用程式中使用的背景內容。

     ctx := context.Background()
    
  3. 建立一個 DefaultAzureCredential 的實例,以便與 Microsoft Entra ID 進行身份驗證。

     credential, err := azidentity.NewDefaultAzureCredential(nil)
     if err != nil {
     	panic(err)
     }
    
  4. 建立回呼函式,以在 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
     }
    
  5. 設定叢集名稱並建構連線 URI。

     clusterName := "<azure-documentdb-cluster-name>"
     uri := fmt.Sprintf("mongodb+srv://%s.global.mongocluster.cosmos.azure.com/", clusterName)
    
  6. 設定 MongoDB 用戶端的驗證認證。

     auth := options.Credential{
     	AuthMechanism:       "MONGODB-OIDC",
     	OIDCMachineCallback: azureIdentityTokenCallback,
     }
    
  7. 使用連線參數、傳輸層安全性 (TLS) 組態和驗證來設定客戶端選項。

     clientOptions := options.Client().
     	ApplyURI(uri).
     	SetConnectTimeout(2 * time.Minute).
     	SetRetryWrites(true).
     	SetTLSConfig(&tls.Config{}).
     	SetAuth(auth)
    
  8. 使用設定的選項建立 MongoDB 用戶端實例。

     client, err := mongo.Connect(clientOptions)
     if err != nil {
     	panic(err)
     }
    
     fmt.Println("Client created")
    
  9. 新增defer語句,以確保應用程式結束時用戶端已正確中斷連線。

     defer func() {
     	if err = client.Disconnect(ctx); err != nil {
     		panic(err)
     	}
     }()
    

執行一般作業

最後,使用官方程式庫處理資料庫、集合和文件的常見工作。 在這裡,您可以使用與 MongoDB 或 DocumentDB 互動的相同類別和方法來管理您的集合和專案。

  1. 依名稱取得您的資料庫的參考。

     database := client.Database("<database-name>")
    
     fmt.Println("Database pointer created")
    
  2. 取得資料庫內您的集合的參考。

     collection := database.Collection("<collection-name>")
    
     fmt.Println("Collection pointer created")
    
  3. 定義 Product 結構來代表您的文件結構。

    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"`
    }
    
  4. 使用針對 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)
    
  5. 使用 collection.FindOne_idcategory 篩選來讀取特定檔。

     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)
    
  6. 使用 category 查詢符合特定 collection.Find 的多個文件。

     queryFilter := bson.D{{Key: "category", Value: "gear-surf-surfboards"}}
     cursor, err := collection.Find(ctx, queryFilter)
     if err != nil {
     	panic(err)
     }
    
  7. 從游標擷取所有相符的檔。

     var products []Product
     if err = cursor.All(ctx, &products); err != nil {
     	panic(err)
     }
    
  8. 逐一查看並顯示查詢中找到的所有產品。

     for _, product := range products {
     	json, err := json.Marshal(product)
     	if err != nil {
     		panic(err)
     	}
     	fmt.Printf("Found document:\t%s\n", string(json))
     }