次の方法で共有


Azure Cosmos DB for MongoDB 仮想コアを使用して Go コンソール アプリを構築する

このガイドでは、Go コンソール アプリケーションを構築して、Azure Cosmos DB for MongoDB 仮想コア クラスターに接続する方法について説明します。 開発環境を設定し、Azure SDK for Go の azidentity パッケージを使用して認証を行い、データベース内のドキュメントに対して一般的な操作を実行します。

[前提条件]

  • 既存の Azure Cosmos DB for MongoDB (仮想コア) クラスター。
  • Azure Cloud ShellAzure CLI の最新バージョン。

    • CLI 参照コマンドをローカルで実行する場合は、 az login コマンドを使用して Azure CLI にサインインします。
  • クラスター用に構成された Microsoft Entra 認証で、あなたの ID に dbOwner ロールが付与されています。

  • 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. MongoDB 仮想コア クラスターと対話する 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. Microsoft Entra ID で認証するために使用する DefaultAzureCredential のインスタンスを作成します。

     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-cosmos-db-mongodb-vcore-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))
     }