練習:使用 Azure Cosmos DB for MongoDB 建立 MongoDB DB 應用程式

已完成

現在可以透過程式設計方式查看如何建立 Azure Cosmos DB for MongoDB 資料庫、集合及新增一些資料了。

此練習可使用 Microsoft Learn 沙箱來完成,該沙箱會提供臨時 Azure 訂用帳戶。 若要啟用沙箱訂用帳戶,您必須使用 Microsoft 帳戶登入。 當您完成此課程模組時,沙箱訂用帳戶會自動刪除。 啟用沙箱後,請使用您的沙箱訂用帳戶認證登入 Azure 入口網站。 請確定您是在 Microsoft Learn 沙箱目錄中工作 - 請見入口網站右上角,您的使用者識別碼下方。 否則,請選取使用者圖示並切換目錄。

提示

您也可選擇使用自己的 Azure 訂用帳戶。 若要這樣做,請使用訂用帳戶的認證來登入 Azure 入口網站。 請確定位於您訂用帳戶所在的目錄,如右上角的使用者識別碼下方所示。 否則,請選取使用者圖示並切換目錄。

使用 Node.js Azure Cosmos DB for MongoDB 來建立 MongoDB 應用程式

使用 Java Azure Cosmos DB for MongoDB 來建立 MongoDB 應用程式

使用 Python Azure Cosmos DB for MongoDB 來建立 MongoDB 應用程式

使用 C# Azure Cosmos DB for MongoDB 來建立 MongoDB 應用程式

在本練習中,您會建立 Azure Cosmos DB for MongoDB 帳戶、資料庫、集合,並將一些文件新增至集合。 您會注意到,此程式碼會與連線至任何 MongoDB 資料庫的方式相同。 接著,您將使用延伸模組命令來建立集合,這些命令可讓您以要求單位/秒 (RUs) 為單位定義集合的輸送量。

準備您的開發環境

如果您沒有可搭配此實驗室使用的 Azure Cosmos DB 帳戶和環境,請遵循下列步驟來執行此動作。 否則,請移至 [將建立資料庫、集合和文件的程式碼新增至 App.js 檔案] 區段。

如果您沒有可搭配此實驗室使用的環境和 Azure Cosmos DB 帳戶,請遵循下列步驟來執行此動作。 否則,請移至 [將建立資料庫、集合和文件的程式碼新增至 App.java 檔案] 區段。

如果您沒有可搭配此實驗室使用的 Azure Cosmos DB 帳戶和環境,請遵循下列步驟來執行此動作。 否則,請移至 [將建立資料庫、集合和文件的程式碼新增至 App.py 檔案] 區段。

如果您沒有可搭配此實驗室使用的環境和 Azure Cosmos DB 帳戶,請遵循下列步驟來執行此動作。 否則,請移至 [將建立資料庫、集合和文件的程式碼新增至 app.cs 檔案] 區段。

  1. 在 Azure Cloud Shell 中,複製並貼上下列命令。

    git clone https://github.com/MicrosoftLearning/mslearn-cosmosdb.git
    cd ~/mslearn-cosmosdb/api-for-mongodb/01-create-mongodb-objects/node/
    
    # Update Azure Cloud Shell node to Version 14.0.0, since the MongoDB driver requires ver 10+
    curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
    source ~/.nvm/nvm.sh
    nvm install 14.0.0
    npm install -g mongodb
    npm link mongodb
    # Check if the node version is now v14.0.0
    node --version
    
    # Create an Azure Cosmos DB for MongoDB account
    bash ../init.sh
    
    git clone https://github.com/MicrosoftLearning/mslearn-cosmosdb.git
    cd ~/mslearn-cosmosdb/api-for-mongodb/01-create-mongodb-objects/java
    # Download and install the Maven project, this will take a minute or two
    mvn archetype:generate -DgroupId=com.fabrikam -DartifactId=AzureApp -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
    # Replace the projects pom.xml file with the github one that has the MongoDB definition
    mv pom.xml1 ./AzureApp/pom.xml
    
    # Create an Azure Cosmos DB for MongoDB account
    bash ../init.sh
    
    git clone https://github.com/MicrosoftLearning/mslearn-cosmosdb.git
    cd ~/mslearn-cosmosdb/api-for-mongodb/01-create-mongodb-objects/python
    # Install the MongoDB Python drivers
    python -m pip install pymongo
    # Create an Azure Cosmos DB for MongoDB account
    bash ../init.sh
    
    git clone https://github.com/MicrosoftLearning/mslearn-cosmosdb.git
    cd ~/mslearn-cosmosdb/api-for-mongodb/01-create-mongodb-objects/csharp
    
    # Add MongoDB driver to DotNet
    dotnet add package MongoDB.Driver --version 2.16.0
    
    # Create an Azure Cosmos DB for MongoDB account
    bash ../init.sh
    

    提示

    如果您未使用實驗室的沙箱,但想要指定您想要建立資料庫和儲存體物件的位置,則請將 -l LOCATIONNAME 參數新增至 init.sh 呼叫。 此外,如果您想要指定資源群組,請將 -r YOURRRESOURCEGROUPNAMEHERE 參數新增至 init.sh 呼叫。

    注意

    此 Bash 指令碼會建立 Azure Cosmos DB for MongoDB 帳戶。 建立此帳戶可能需要 5-10 分鐘的時間,這段時間可以來杯咖啡或來杯茶。

    提示

    如果您回來時 Cloud Shell 已重設,則請在 Cloud Shell 中執行下列命令來使用 Node 第 14 版,否則下一節中的程式碼將會失敗。

    1. source ~/.nvm/nvm.sh
    2. nvm install 14.0.0
    3. npm link mongodb
  2. 當 bash init.sh 檔案執行完成時,請在某處複製所傳回的 [連接字串]、[Cosmos DB 帳戶名稱] 和 [資源群組名稱],我們將在下一節中使用這些項目。 您也可以檢閱帳戶建立指令碼所傳回的 JSON,該指令碼位於連接字串之前。 如果您在 JSON 內進行查看,應該會看到屬性 "kind": "MongoDB"

    注意

    請注意,您也可以使用 Azure 入口網站找到 [連接字串][Cosmos DB 帳戶名稱][資源群組名稱]

將建立資料庫、集合和文件的程式碼新增至 App.js 檔案

現在是時候新增 JavaScript 程式碼來建立資料庫、集合,並將文件新增至集合。

將建立資料庫、集合和文件的程式碼新增至 App.java 檔案

現在是時候新增 Java 程式碼來建立資料庫、集合,並將文件新增至集合。

將建立資料庫、集合和文件的程式碼新增至 App.py 檔案

現在是時候新增 Python 程式碼來建立資料庫、集合,並將文件新增至集合。

將建立資料庫、集合和文件的程式碼新增至 app.cs 檔案

現在是時候新增 C# 程式碼來建立資料庫、集合,並將文件新增至集合。

  1. 若尚未開啟,則請開啟 Azure Cloud Shell。

  2. 執行下列命令以開啟程式碼編輯器。

    cd ~/mslearn-cosmosdb/api-for-mongodb/01-create-mongodb-objects/node/
    code App.js
    
    cd ~/mslearn-cosmosdb/api-for-mongodb/01-create-mongodb-objects/java/AzureApp
    code ./src/main/java/com/fabrikam/App.java
    
    cd ~/mslearn-cosmosdb/api-for-mongodb/01-create-mongodb-objects/python
    code App.py
    
    cd ~/mslearn-cosmosdb/api-for-mongodb/01-create-mongodb-objects/csharp
    code app.cs
    
  3. 將下列程式碼複製到 App 檔案。 別忘了,您必須取代上一節中所複製連接字串的 URI 值

    程式碼的這個部分使用 MongoDB 驅動程式,並使用與 Azure Cosmos DB 的連接字串,如同您通常會使用與任何 MongoDB 伺服器的連接字串一樣。 然後,程式碼會定義並開啟與 Azure Cosmos DB 帳戶的連線。

    // Uses the MongoDB driver
    const {MongoClient} = require("mongodb");
    
    async function main() {
    
        // One of the values you copied earlier was the connection string, replace it in the following line 
        var url = "TheConnectionStringYouCopiedEarlier";
    
        // define the connection using the MongoClient method ane the url above
        var mongoClient = new MongoClient(url, function(err,client)
        {
            if (err)
            {
                console.log("error connecting")
            }
        }
        );
    
        // open the connection
        await mongoClient.connect();
    
    
    package com.fabrikam;
    
    // Uses the MongoDB driver
    import com.mongodb.MongoClient;
    import com.mongodb.MongoClientURI;
    import com.mongodb.client.MongoDatabase;
    import com.mongodb.client.MongoCollection;
    import org.bson.Document;
    import static com.mongodb.client.model.Filters.eq;
    
    public class App {
        public static void main(String[] args) {
    
            // One of the values you copied earlier was the connection string, replace it in the following line 
            MongoClientURI uri = new MongoClientURI("TheConnectionStringYouCopiedEarlier");
    
            MongoClient mongoClient = null;
            try {
                // define the connection using the MongoClient method ane the url above and open the connection 
                mongoClient = new MongoClient(uri);
    
    
    # Use the MongoDB drivers
    import pymongo
    
    
    def main():
        # One of the values you copied earlier was the connection string, replace it in the following line 
        uri = "TheConnectionStringYouCopiedEarlier"
    
        # We use the "MongoClient" method and the "uri" value to connect to the account 
        client = pymongo.MongoClient(uri)
    
        ```
    
    
    // Uses the MongoDB driver
    using MongoDB.Driver;
    using MongoDB.Bson;
    using System;
    
    public class Products {
        public ObjectId Id { get; set; }  
        public int ProductId { get; set; }
        public string name { get; set; }
    }
    
    class App {
        public static void Main (string[] args) {
    
        // One of the values you copied earlier was the connection string, replace it in the following line 
        string connectionString = 
            @"TheConnectionStringYouCopiedEarlier";
    
        MongoClientSettings settings = MongoClientSettings.FromUrl(new MongoUrl(connectionString));
    
        // define the connection using the MongoClient method ane the connectionString above and open the connection 
        var mongoClient = new MongoClient(settings);
    
    
  4. 下一個步驟會連線到 products 資料庫。 如果這個資料庫不存在,則只有在同時在同一個連線中建立集合或是使用延伸模組命令時,才會加以建立。 將下列內容新增至編輯器中的指令碼。

    // connect to the database "products"
    var ProductDatabase = mongoClient.db("products");
    
        // connect to the database "products"
        MongoDatabase ProductDatabase = mongoClient.getDatabase("products");
    
    
        # connect to the database "products"
        ProductDatabase = client["products"]
    
    
        // connect to the database "products"
        var ProductDatabase = mongoClient.GetDatabase("products");
    
    
  5. 接下來,如果文件集合已經存在,我們會連線到文件集合,然後將一份文件新增至集合。 如果集合不存在,則此程式碼會在其也在相同連線中對該集合執行作業 (例如將文件新增至集合) 的情況下建立集合,或使用延伸模組命令來建立集合。 將下列內容新增至編輯器中的指令碼。

    
      // create a collection "documents" and add one document for "bread"
      var collection = ProductDatabase.collection('documents');
      var insertResult = await collection.insertOne({ ProductId: 1, name: "bread" });
    
                // create a collection "documents" and add one document for "bread" 
                MongoCollection collection = ProductDatabase.getCollection("products");
    
                collection.insertOne(new Document()
                            .append("ProductId", 1)
                            .append("name", "bread"));
    
    
        # create a collection "products" and add one document for "bread"
        collection = ProductDatabase["products"]
        collection.insert_one({ "ProductId": 1, "name": "bread" })
    
    
        // create a collection "products" and add one document for "bread" 
        var mongoCollection = ProductDatabase.GetCollection<Products>("products");
    
        Products Product = new Products {ProductId=1,name="bread"};
        mongoCollection.InsertOne (Product);
    
    
  6. 現在,讓我們搜尋插入的文件,並讓其顯示至殼層。 將下列內容新增至編輯器中的指令碼。

      // return data where ProductId = 1
      const findProduct = await collection.find({ProductId: 1});
      await findProduct.forEach(console.log);
    
                // return data where ProductId = 1
                Document findProduct = (Document) collection.find(eq("ProductId", 1)).first();
                System.out.println(findProduct.toJson());
            }
    
        # return data where ProductId = 1
        Product_1 = collection.find_one({"ProductId": 1})
    
        print(Product_1)
    
    
        // return data where ProductId = 1
        Products ProductFound =  mongoCollection.Find(_ => _.ProductId == 1).FirstOrDefault();
        Console.WriteLine ("Id: {0}, ProductId: {1}, name: \'{2}\'", ProductFound.Id, ProductFound.ProductId, ProductFound.name);
      }
    }
    
  7. 最後,讓我們關閉連線。 將下列內容新增至編輯器中的指令碼。

      // close the connection
      mongoClient.close();
    }
    
    main();
    
            // close the connection
            finally {
                if (mongoClient != null) {
                    mongoClient.close();
                }
            }
        }
    }
    
        # close the connection
        client.close()
    
    if __name__ == '__main__':
        main()
    
    // Note C# doesn't need to close the connection, it disposes of the connection when the program ends.
    
  8. 指令碼看起來應該如下:

    // Uses the MongoDB driver
    const {MongoClient} = require("mongodb");
    
    async function main() {
    
      // One of the values you copied earlier was the connection string, replace it in the following line
      var url = "TheConnectionStringYouCopiedEarlier";
    
      // define the connection using the MongoClient method ane the url above
      var mongoClient = new MongoClient(url, function(err,client)
        {
          if (err)
          {
            console.log("error connecting")
          }
        }
      );
    
      // open the connection
      await mongoClient.connect();
    
      // connect to the database "products"
      var ProductDatabase = mongoClient.db("products");
    
      // create a collection "documents" and add one document for "bread"
      var collection = ProductDatabase.collection('documents');
      var insertResult = await collection.insertOne({ ProductId: 1, name: "bread" });
    
      // return data where ProductId = 1
      const findProduct = await collection.find({ProductId: 1});
      await findProduct.forEach(console.log);
    
      // close the connection
      mongoClient.close();
    }
    
    main();
    
    package com.fabrikam;
    
    // Uses the MongoDB driver
    import com.mongodb.MongoClient;
    import com.mongodb.MongoClientURI;
    import com.mongodb.client.MongoDatabase;
    import com.mongodb.client.MongoCollection;
    import org.bson.Document;
    import static com.mongodb.client.model.Filters.eq;
    
    public class App {
        public static void main(String[] args) {
    
            // One of the values you copied earlier was the connection string, replace it in the following line
            MongoClientURI uri = new MongoClientURI("TheConnectionStringYouCopiedEarlier");
    
            MongoClient mongoClient = null;
            try {
                // define the connection using the MongoClient method ane the url above and open the connection 
                mongoClient = new MongoClient(uri);
    
                // connect to the database "products"
                MongoDatabase ProductDatabase = mongoClient.getDatabase("products");
    
                // create a collection "products" and add one document for "bread" 
                MongoCollection collection = ProductDatabase.getCollection("products");
    
                collection.insertOne(new Document()
                            .append("ProductId", 1)
                            .append("name", "bread"));
    
                // return data where ProductId = 1
                Document findProduct = (Document) collection.find(eq("ProductId", 1)).first();
                System.out.println(findProduct.toJson());
            }
            // close the connection
            finally {
                if (mongoClient != null) {
                    mongoClient.close();
                }
            }
        }
    }
    
    # Use the MongoDB drivers
    import pymongo
    
    def main():
        # One of the values you copied earlier was the connection string, replace it in the following line
        uri = "TheConnectionStringYouCopiedEarlier"
    
        # We use the "MongoClient" method and the "uri" value to connect to the account 
        client = pymongo.MongoClient(uri)
    
        # connect to the database "products"
        ProductDatabase = client["products"]
    
        # create a collection "products" and add one document for "bread"
        collection = ProductDatabase["products"]
        collection.insert_one({ "ProductId": 1, "name": "bread" })
    
        # return data where ProductId = 1
        Product_1 = collection.find_one({"ProductId": 1})
    
        print(Product_1)
    
        # close the connection
        client.close()
    
    if __name__ == '__main__':
        main()
    
    // Uses the MongoDB driver
    using MongoDB.Driver;
    using MongoDB.Bson;
    using System;
    
      public class Products {
        public ObjectId Id { get; set; }  
        public int ProductId { get; set; }
        public string name { get; set; }
      }
    
    class App {
      public static void Main (string[] args) {
    
        // One of the values you copied earlier was the connection string, replace it in the following line
        string connectionString = 
          @"TheConnectionStringYouCopiedEarlier";
    
        MongoClientSettings settings = MongoClientSettings.FromUrl(new MongoUrl(connectionString));
    
        // define the connection using the MongoClient method ane the connectionString above and open the connection 
        var mongoClient = new MongoClient(settings);
    
        // connect to the database "products"
        var ProductDatabase = mongoClient.GetDatabase("products");
    
        // create a collection "products" and add one document for "bread" 
        var mongoCollection = ProductDatabase.GetCollection<Products>("products");
    
        Products Product = new Products {ProductId=1,name="bread"};
        mongoCollection.InsertOne (Product);
    
        // return data where ProductId = 1
        Products ProductFound =  mongoCollection.Find(_ => _.ProductId == 1).FirstOrDefault();
        Console.WriteLine ("Id: {0}, ProductId: {1}, name: \'{2}\'", ProductFound.Id, ProductFound.ProductId, ProductFound.name);
      }
    }
    
  9. 讓我們繼續進行,並儲存程式。 選取程式碼編輯器的右上角,然後選取 [儲存] (或 [Ctrl+S])。 現在選取 [關閉編輯器] (或 Ctrl+Q) 以返回殼層。

  10. 現在讓我們使用下列命令來執行應用程式。

    node App.js
    
    mvn clean compile exec:java
    
    python App.py
    
    dotnet run
    
  11. 此指令碼應該會傳回類似下列的結果。 這表示我們已建立資料庫、集合,並對其新增文件。

    {
      _id: new ObjectId("62aed08663c0fd62d30240db"),
      ProductId: 1,
      name: 'bread'
    }
    
    INFO: Opened connection [connectionId{localValue:3, serverValue:74678510}] to learn-account-cosmos-665601-westus.mongo.cosmos.azure.com:10255
    { "_id" : { "$oid" : "62afa8c3dff473012e7b7910" }, "ProductId" : 1, "name" : "bread" }
    Jun 19, 2022 10:52:59 PM com.mongodb.diagnostics.logging.JULLogger log
    INFO: Closed connection [connectionId{localValue:3, serverValue:74678510}] to learn-account-cosmos-665601-westus.mongo.cosmos.azure.com:10255 because the pool has been closed.
    
    {'_id': ObjectId('62afecc3a04e32b92451ac5d'), 'ProductId': 1, 'name': 'bread'}
    
    Id: 62affed8147b5206db146298, ProductId: 1, name: 'bread'
    

如您所見,此程式碼與您所執行以在 MongoDB 資料庫上建立資料庫、集合和文件的程式碼相同。 因此,如果您已經熟悉如何建立連線至 MongoDB 的應用程式,則 Azure Cosmos DB for MongoDB 程式設計應該很透明。

受控識別

針對生產工作負載,我們建議使用受控識別向 Azure Cosmos DB 進行驗證。 如此一來,您就不需要將連接字串儲存在程式碼中。 在下一節中,我們將使用受控識別向 Azure Cosmos DB 進行驗證。

在實際執行環境中,您應該使用具有最低必要權限的受控識別。 您可以建立一或多個使用者指派的受控識別,並將其指派給 Azure Cosmos DB 帳戶。 在此實驗室中,我們要為 Azure Cosmos DB 帳戶建立系統指派的受控識別。

  1. 在 Azure 入口網站中,瀏覽至您稍早建立的 Azure Cosmos DB 帳戶。
  2. 在左側功能表的 [設定] 下方,選取 [身分識別]
  3. 在 [身分識別] 窗格中,選取 [系統指派]
  4. 針對 [狀態] 選取 [開啟]
  5. 選取儲存
  6. 建立受控識別需要一兩分鐘的時間。

建立受控識別之後,我們必須將 Azure Cosmos DB 帳戶的必要權限指派給受控識別。 是時候使用 RBAC (角色型存取控制) 對受控識別指派必要權限了。 在此實驗室中,我們會將參與者角色指派給受控識別,以允許其對 Azure Cosmos DB 帳戶讀取和寫入資料。 在實際執行環境中,您應該指派所需的最低權限角色。

  1. 在 Azure 入口網站中,瀏覽至您稍早建立的 Azure Cosmos DB 帳戶。
  2. 在左側功能表中的 [設定] 底下,選取 [存取控制 (IAM)]
  3. 選取 [+ 新增],然後選取 [新增角色指派]
  4. 在 [特殊權限管理員角色] 底下,選取 [參與者],然後選取 [下一步]
  5. 在 [成員] 底下選取 [受控識別],然後選取 [+ 選取成員]
  6. 在 [選取受控識別] 窗格中,搜尋您稍早建立的受控識別並將其選取,然後選取 [檢閱 + 指派]

您現在已將受控識別指派給 Azure Cosmos DB 帳戶,並且具有必要權限。 現在讓我們使用受控識別向 Azure Cosmos DB 帳戶進行驗證。

使用延伸模組命令來管理「適用於 MongoDB 的 Azure Cosmos DB API」中儲存的資料

雖然上述程式碼在連線到 MongoDB 伺服器,然後連線到 Azure Cosmos DB for MongoDB 之間皆為相同,但此連線可能無法利用 Azure Cosmos DB 功能。 這表示若使用預設驅動程式方法來建立我們的集合,則也會使用預設的 Azure Cosmos DB 帳戶參數來建立這些集合。 因此,我們無法使用這些方法來定義建立參數 (例如輸送量、分區金鑰或自動調整設定)。

藉由使用適用於 MongoDB 的 Azure Cosmos DB API,您可以享有 Cosmos DB 的優點。 這些優點包括全域散發、自動分區化、高可用性、延遲保證、自動、待用加密、備份等等。 加上保留 MongoDB 應用程式投資的額外優點。 您可以使用任何開放原始碼 MongoDB 用戶端驅動程式,與適用於 MongoDB 的 Azure Cosmos DB API 通訊。 Azure Cosmos DB 適用於 MongoDB 的 API 遵循 MongoDB 有線通訊協定,支援使用現有的用戶端驅動程式。

讓我們建立一些程式碼,以允許我們建立集合,並定義其分區金鑰和輸送量。

  1. 若尚未開啟,則請開啟 Azure Cloud Shell。

  2. 執行下列命令以開啟程式碼編輯器。

    cd ~/mslearn-cosmosdb/api-for-mongodb/01-create-mongodb-objects/node
    code App.js
    
    cd ~/mslearn-cosmosdb/api-for-mongodb/01-create-mongodb-objects/java/AzureApp
    code ./src/main/java/com/fabrikam/App.java
    
    cd ~/mslearn-cosmosdb/api-for-mongodb/01-create-mongodb-objects/python
    code App.py
    
    cd ~/mslearn-cosmosdb/api-for-mongodb/01-create-mongodb-objects/csharp
    code app.cs
    
  3. 將下列程式碼複製至檔案。

    import { DefaultAzureCredential, ClientSecretCredential } from "@azure/identity";
    const { MongoClient, ObjectId } = require('mongodb');
    import axios from "axios";
    
    async function main() {
        // Environment variables
        const endpoint = process.env.AZURE_COSMOS_RESOURCEENDPOINT;
        const listConnectionStringUrl = process.env.AZURE_COSMOS_LISTCONNECTIONSTRINGURL;
        const scope = process.env.AZURE_COSMOS_SCOPE;
    
        // For system-assigned managed identity.
        const credential = new DefaultAzureCredential();
    
        // Acquire the access token
        const accessToken = await credential.getToken(scope);
    
        // Get the connection string
        const config = {
            method: 'post',
            url: listConnectionStringUrl,
            headers: {
                'Authorization': 'Bearer ${accessToken.token}'
            }
        };
        const response = await axios(config);
        const keysDict = response.data;
        const connectionString = keysDict['connectionStrings'][0]['connectionString'];
    
        // Connect to Azure Cosmos DB for MongoDB
        const mongoClient = new MongoClient(connectionString);
    
        // open the connection
        await mongoClient.connect();
    
    
    package com.fabrikam;
    
    import com.mongodb.MongoClient;
    import com.mongodb.MongoClientURI;
    import com.mongodb.client.MongoCollection;
    import com.mongodb.client.MongoDatabase;
    import com.mongodb.client.model.Filters;
    import javax.net.ssl.*;
    import java.net.InetSocketAddress;
    import com.azure.identity.*;
    import com.azure.core.credential.*;
    import java.net.http.*;
    import java.net.URI;
    
    public class App {
        public static void main(String[] args) {
            // Environment variables
            String endpoint = System.getenv("AZURE_COSMOS_RESOURCEENDPOINT");
            String listConnectionStringUrl = System.getenv("AZURE_COSMOS_LISTCONNECTIONSTRINGURL");
            String scope = System.getenv("AZURE_COSMOS_SCOPE");
    
            // For system-assigned managed identity.
            DefaultAzureCredential defaultCredential = new DefaultAzureCredentialBuilder().build();
    
    
        MongoClient mongoClient = null;
    
        try {
            // Acquire the access token
            AccessToken accessToken = defaultCredential
                .getToken(new TokenRequestContext().addScopes(scope))
                .block();
            String token = accessToken.getToken();
    
            // Retrieve the connection string
            HttpClient client = HttpClient.newBuilder().build();
            HttpRequest request = HttpRequest.newBuilder()
                .uri(new URI(listConnectionStringUrl))
                .header("Authorization", "Bearer " + token)
                .POST(HttpRequest.BodyPublishers.noBody())
                .build();
            HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
    
            JSONParser parser = new JSONParser();
            JSONObject responseBody = parser.parse(response.body());
            List<Map<String, String>> connectionStrings = responseBody.get("connectionStrings");
            String connectionString = connectionStrings.get(0).get("connectionString");
    
            // Connect to Azure Cosmos DB for MongoDB
            MongoClientURI uri = new MongoClientURI(connectionString);
            mongoClient = new MongoClient(uri);
    
    
    import os
    import pymongo
    import requests
    from azure.identity import ManagedIdentityCredential, ClientSecretCredential
    
    def main():
        # Environment variables
        endpoint = os.getenv('AZURE_COSMOS_RESOURCEENDPOINT')
        listConnectionStringUrl = os.getenv('AZURE_COSMOS_LISTCONNECTIONSTRINGURL')
        scope = os.getenv('AZURE_COSMOS_SCOPE')
    
        # For system-assigned managed identity
        cred = ManagedIdentityCredential()
    
        # Get the connection string
        session = requests.Session()
        token = cred.get_token(scope)
        response = session.post(listConnectionStringUrl, headers={"Authorization": "Bearer {}".format(token.token)})
        keys_dict = response.json()
        conn_str = keys_dict["connectionStrings"][0]["connectionString"]
    
        # Connect to Azure Cosmos DB for MongoDB
        client = pymongo.MongoClient(conn_str)
    
    
    using MongoDB.Driver;
    using Azure.Identity;
    using Azure.Core;
    using System;
    using System.Net.Http;
    using System.Text.Json;
    using System.Collections.Generic;
    using System.Threading.Tasks;
    
    public class Products
    {
        public int ProductId { get; set; }
        public string name { get; set; }
    }
    
    class App
    {
        public static async Task Main(string[] args)
        {
            // Environment variables
            var endpoint = Environment.GetEnvironmentVariable("AZURE_COSMOS_RESOURCEENDPOINT");
            var listConnectionStringUrl = Environment.GetEnvironmentVariable("AZURE_COSMOS_LISTCONNECTIONSTRINGURL");
            var scope = Environment.GetEnvironmentVariable("AZURE_COSMOS_SCOPE");
    
            // For system-assigned identity.
            var tokenProvider = new DefaultAzureCredential();
    
            // Acquire the access token.
            AccessToken accessToken = await tokenProvider.GetTokenAsync(
                new TokenRequestContext(scopes: new[] { scope }));
    
            // Get the connection string.
            using var httpClient = new HttpClient();
            httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {accessToken.Token}");
            var response = await httpClient.PostAsync(listConnectionStringUrl, null);
            response.EnsureSuccessStatusCode();
            var responseBody = await response.Content.ReadAsStringAsync();
    
            // Parse the connection string.
            var connectionStrings = JsonSerializer.Deserialize<Dictionary<string, List<Dictionary<string, string>>>>(responseBody);
            string connectionString = connectionStrings["connectionStrings"][0]["connectionString"];
    
            // Initialize the MongoClient with the connection string.
            var mongoClient = new MongoClient(connectionString);
    
    
  4. 下一個步驟會連線到 employees 資料庫。 如果這個資料庫不存在,則只有在同時在同一個連線中建立集合或是使用延伸模組命令時,才會加以建立。 將下列內容新增至編輯器中的指令碼。

      // connect to the database "HumanResources"
      var EmployeeDatabase = mongoClient.db("HumanResources");
    
    
                // connect to the database "HumanResources"
                MongoDatabase EmployeeDatabase = mongoClient.getDatabase("HumanResources");
    
    
        # connect to the database "HumanResources"
        EmployeeDatabase = client["HumanResources"]
    
    
         // connect to the database "HumanResources"
        var EmployeeDatabase = mongoClient.GetDatabase("HumanResources");
    
    
  5. 到目前為止,其看起來就像上一節中的程式碼一樣。 在此步驟中,我們會利用延伸模組命令並建立自訂動作。 此動作可讓我們定義集合的輸送量和分區金鑰。 接著,步驟會提供 Azure Cosmos DB 建立集合時要使用的參數。 將下列內容新增至編輯器中的指令碼。

      // create the Employee collection with a throughput of 1000 RUs and with EmployeeId as the sharding key
      var result = EmployeeDatabase.command({customAction: "CreateCollection", collection: "Employee", offerThroughput: 1000, shardKey: "EmployeeId"});
    
    
                // create the Employee collection with a throughput of 1000 RUs and with EmployeeId as the sharding key
                Document employeeCollectionDef = new Document();
                employeeCollectionDef.append("customAction", "CreateCollection");
                employeeCollectionDef.append("collection", "Employee");
                employeeCollectionDef.append("offerThroughput", 1000);
                employeeCollectionDef.append("shardKey", "EmployeeId");
    
                Document result = EmployeeDatabase.runCommand(employeeCollectionDef);
    
    
        # create the Employee collection with a throughput of 1000 RUs and with EmployeeId as the sharding key
        EmployeeDatabase.command({'customAction': "CreateCollection", 'collection': "Employee", 'offerThroughput': 1000, 'shardKey': "EmployeeId"})
    
    
        // create the Employee collection with a throughput of 1000 RUs and with EmployeeId as the sharding key
        var result = EmployeeDatabase.RunCommand<BsonDocument>(@"{customAction: ""CreateCollection"", collection: ""Employee"", offerThroughput: 1000, shardKey: ""EmployeeId""}");
    
    
  6. 其餘部分與上一個範例相同。 我們會連線到集合,插入一些資料列,最後查詢並輸出資料列。 將下列內容新增至編輯器中的指令碼。

      // Connect to the collection "Employee" and add two documents for "Marcos" and "Tam" 
      var collection = EmployeeDatabase.collection('Employee');
    
      var insertResult = await collection.insertOne({EmployeeId: 1, email: "Marcos@fabrikam.com", name: "Marcos"});
      insertResult = await collection.insertOne({EmployeeId: 2, email: "Tam@fabrikam.com", name: "Tam"});
    
      // return data where ProductId = 1
      const findProduct = await collection.find({EmployeeId: 1});
      await findProduct.forEach(console.log);
    
      // close the connection
      mongoClient.close();
    }
    
    main();
    
                // Connect to the collection "Employee" and add two documents for "Marcos" and "Tam" 
                MongoCollection collection = EmployeeDatabase.getCollection("Employee");
    
                collection.insertOne(new Document()
                            .append("EmployeeId", 1)
                            .append("email","Marcos@fabrikam.com")
                            .append("name", "Marcos"));
    
                collection.insertOne(new Document()
                            .append("EmployeeId", 2)
                            .append("email","Tam@fabrikam.com")
                            .append("name", "Tam"));
    
                // return data where EmployeeId = 1
                Document findEmployee = (Document) collection.find(eq("EmployeeId", 1)).first();
                System.out.println(findEmployee.toJson());
            }
            // close the connection
            finally {
                if (mongoClient != null) {
                    mongoClient.close();
                }
            }
        }
    }
    
        # Connect to the collection "Employee" and add two documents for "Marcos" and "Tam"
        collection = EmployeeDatabase["Employee"]
        collection.insert_one({ "EmployeeId": 1, "email": "Marcos@fabrikan.com", "name": "Marcos" })
        collection.insert_one({ "EmployeeId": 2, "email": "Tam@fabrikan.com", "name": "Tam" })
    
        # return data where ProductId = 1
        Product_1 = collection.find_one({"EmployeeId": 1})
    
        print(Product_1)
    
        # close the connection
        client.close()
    
    if __name__ == '__main__':
        main()
    
        // Connect to the collection "Employee" and add two documents for "Marcos" and "Tam" 
        var mongoCollection = EmployeeDatabase.GetCollection<Employees>("Employee");
    
        Employees Employee = new Employees {EmployeeId=1,email="Marcos@fabrikam.com",name="Marcos"};
        mongoCollection.InsertOne (Employee);
    
        Employee = new Employees {EmployeeId=2,email="Tam@fabrikam.com",name="Tam"};
        mongoCollection.InsertOne (Employee);
    
        // return data where EmployeeId = 1
        Employees EmployeeFound =  mongoCollection.Find(_ => _.EmployeeId == 1).FirstOrDefault();
        Console.WriteLine ("Id: {0}, EmployeeId: {1}, email: \'{2}\', name: \'{3}\'", EmployeeFound.Id, EmployeeFound.EmployeeId, EmployeeFound.email, EmployeeFound.name);
      }
    }
    
  7. 指令碼看起來應該如下:

    import { DefaultAzureCredential, ClientSecretCredential } from "@azure/identity";
    const { MongoClient, ObjectId } = require('mongodb');
    import axios from "axios";
    
    async function main() {
        // Environment variables
        const endpoint = process.env.AZURE_COSMOS_RESOURCEENDPOINT;
        const listConnectionStringUrl = process.env.AZURE_COSMOS_LISTCONNECTIONSTRINGURL;
        const scope = process.env.AZURE_COSMOS_SCOPE;
    
        // For system-assigned managed identity.
        const credential = new DefaultAzureCredential();
    
        // Acquire the access token
        const accessToken = await credential.getToken(scope);
    
        // Get the connection string
        const config = {
            method: 'post',
            url: listConnectionStringUrl,
            headers: {
                'Authorization': 'Bearer ${accessToken.token}'
            }
        };
        const response = await axios(config);
        const keysDict = response.data;
        const connectionString = keysDict['connectionStrings'][0]['connectionString'];
    
        // Connect to Azure Cosmos DB for MongoDB
        const mongoClient = new MongoClient(connectionString);
    
        // open the connection
        await mongoClient.connect();
    
        // connect to the database "HumanResources"
        var EmployeeDatabase = mongoClient.db("HumanResources");
    
        // create the Employee collection with a throughput of 1000 RUs and with EmployeeId as the sharding key
        var result = EmployeeDatabase.command({customAction: "CreateCollection", collection: "Employee", offerThroughput: 1000, shardKey: "EmployeeId"});
    
        // Connect to the collection "Employee" and add two documents for "Marcos" and "Tam" 
        var collection = EmployeeDatabase.collection('Employee');
    
        var insertResult = await collection.insertOne({EmployeeId: 1, email: "Marcos@fabrikam.com", name: "Marcos"});
        insertResult = await collection.insertOne({EmployeeId: 2, email: "Tam@fabrikam.com", name: "Tam"});
    
        // return data where ProductId = 1
        const findProduct = await collection.find({EmployeeId: 1});
        await findProduct.forEach(console.log);
    
        // close the connection
        mongoClient.close();
    }
    
    main();
    
    package com.fabrikam;
    
    import com.mongodb.MongoClient;
    import com.mongodb.MongoClientURI;
    import com.mongodb.client.MongoCollection;
    import com.mongodb.client.MongoDatabase;
    import com.mongodb.client.model.Filters;
    import javax.net.ssl.*;
    import java.net.InetSocketAddress;
    import com.azure.identity.*;
    import com.azure.core.credential.*;
    import java.net.http.*;
    import java.net.URI;
    
    public class App {
        public static void main(String[] args) {
            // Environment variables
            String endpoint = System.getenv("AZURE_COSMOS_RESOURCEENDPOINT");
            String listConnectionStringUrl = System.getenv("AZURE_COSMOS_LISTCONNECTIONSTRINGURL");
            String scope = System.getenv("AZURE_COSMOS_SCOPE");
    
            // For system-assigned managed identity.
            DefaultAzureCredential defaultCredential = new DefaultAzureCredentialBuilder().build();
    
    
            MongoClient mongoClient = null;
    
            try {
                // Acquire the access token
                AccessToken accessToken = defaultCredential
                    .getToken(new TokenRequestContext().addScopes(scope))
                    .block();
                String token = accessToken.getToken();
    
                // Retrieve the connection string
                HttpClient client = HttpClient.newBuilder().build();
                HttpRequest request = HttpRequest.newBuilder()
                    .uri(new URI(listConnectionStringUrl))
                    .header("Authorization", "Bearer " + token)
                    .POST(HttpRequest.BodyPublishers.noBody())
                    .build();
                HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
    
                JSONParser parser = new JSONParser();
                JSONObject responseBody = parser.parse(response.body());
                List<Map<String, String>> connectionStrings = responseBody.get("connectionStrings");
                String connectionString = connectionStrings.get(0).get("connectionString");
    
                // Connect to Azure Cosmos DB for MongoDB
                MongoClientURI uri = new MongoClientURI(connectionString);
                mongoClient = new MongoClient(uri);
    
                // connect to the database "HumanResources"
                MongoDatabase EmployeeDatabase = mongoClient.getDatabase("HumanResources");
    
                // create the Employee collection with a throughput of 1000 RUs and with EmployeeId as the sharding key
                Document employeeCollectionDef = new Document();
                employeeCollectionDef.append("customAction", "CreateCollection");
                employeeCollectionDef.append("collection", "Employee");
                employeeCollectionDef.append("offerThroughput", 1000);
                employeeCollectionDef.append("shardKey", "EmployeeId");
    
                Document result = EmployeeDatabase.runCommand(employeeCollectionDef);
    
                // Connect to the collection "Employee" and add two documents for "Marcos" and "Tam" 
                MongoCollection collection = EmployeeDatabase.getCollection("Employee");
    
                collection.insertOne(new Document()
                        .append("EmployeeId", 1)
                        .append("email","Marcos@fabrikam.com")
                        .append("name", "Marcos"));
    
                collection.insertOne(new Document()
                        .append("EmployeeId", 2)
                        .append("email","Tam@fabrikam.com")
                        .append("name", "Tam"));
    
                // return data where EmployeeId = 1
                Document findEmployee = (Document) collection.find(eq("EmployeeId", 1)).first();
                System.out.println(findEmployee.toJson());
            }
            // close the connection
            finally {
                if (mongoClient != null) {
                    mongoClient.close();
                }
            }
        }
    }
    
    import os
    import pymongo
    import requests
    from azure.identity import ManagedIdentityCredential, ClientSecretCredential
    
    def main():
        # Environment variables
        endpoint = os.getenv('AZURE_COSMOS_RESOURCEENDPOINT')
        listConnectionStringUrl = os.getenv('AZURE_COSMOS_LISTCONNECTIONSTRINGURL')
        scope = os.getenv('AZURE_COSMOS_SCOPE')
    
        # For system-assigned managed identity
        cred = ManagedIdentityCredential()
    
        # Get the connection string
        session = requests.Session()
        token = cred.get_token(scope)
        response = session.post(listConnectionStringUrl, headers={"Authorization": "Bearer {}".format(token.token)})
        keys_dict = response.json()
        conn_str = keys_dict["connectionStrings"][0]["connectionString"]
    
        # Connect to Azure Cosmos DB for MongoDB
        client = pymongo.MongoClient(conn_str)
    
        # connect to the database "HumanResources"
        EmployeeDatabase = client["HumanResources"]
    
        # create the Employee collection with a throughput of 1000 RUs and with EmployeeId as the sharding key
        EmployeeDatabase.command({'customAction': "CreateCollection", 'collection': "Employee", 'offerThroughput': 1000, 'shardKey': "EmployeeId"})
    
        # Connect to the collection "Employee" and add two documents for "Marcos" and "Tam"
        collection = EmployeeDatabase["Employee"]
        collection.insert_one({ "EmployeeId": 1, "email": "Marcos@fabrikan.com", "name": "Marcos" })
        collection.insert_one({ "EmployeeId": 2, "email": "Tam@fabrikan.com", "name": "Tam" })
    
        # return data where ProductId = 1
        Product_1 = collection.find_one({"EmployeeId": 1})
    
        print(Product_1)
    
        # close the connection
        client.close()
    
    if __name__ == '__main__':
        main()
    
    using MongoDB.Driver;
    using Azure.Identity;
    using Azure.Core;
    using System;
    using System.Net.Http;
    using System.Text.Json;
    using System.Collections.Generic;
    using System.Threading.Tasks;
    
    public class Products
    {
        public int ProductId { get; set; }
        public string name { get; set; }
    }
    
    class App
    {
        public static async Task Main(string[] args)
        {
            // Environment variables
            var endpoint = Environment.GetEnvironmentVariable("AZURE_COSMOS_RESOURCEENDPOINT");
            var listConnectionStringUrl = Environment.GetEnvironmentVariable("AZURE_COSMOS_LISTCONNECTIONSTRINGURL");
            var scope = Environment.GetEnvironmentVariable("AZURE_COSMOS_SCOPE");
    
            // For system-assigned identity.
            var tokenProvider = new DefaultAzureCredential();
    
            // Acquire the access token.
            AccessToken accessToken = await tokenProvider.GetTokenAsync(
                new TokenRequestContext(scopes: new[] { scope }));
    
            // Get the connection string.
            using var httpClient = new HttpClient();
            httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {accessToken.Token}");
            var response = await httpClient.PostAsync(listConnectionStringUrl, null);
            response.EnsureSuccessStatusCode();
            var responseBody = await response.Content.ReadAsStringAsync();
    
            // Parse the connection string.
            var connectionStrings = JsonSerializer.Deserialize<Dictionary<string, List<Dictionary<string, string>>>>(responseBody);
            string connectionString = connectionStrings["connectionStrings"][0]["connectionString"];
    
            // Initialize the MongoClient with the connection string.
            var mongoClient = new MongoClient(connectionString);
    
            // connect to the database "HumanResources"
            var EmployeeDatabase = mongoClient.GetDatabase("HumanResources");
    
            // create the Employee collection with a throughput of 1000 RUs and with EmployeeId as the sharding key
            var result = EmployeeDatabase.RunCommand<BsonDocument>(@"{customAction: ""CreateCollection"", collection: ""Employee"", offerThroughput: 1000, shardKey: ""EmployeeId""}");
    
            // Connect to the collection "Employee" and add two documents for "Marcos" and "Tam" 
            var mongoCollection = EmployeeDatabase.GetCollection<Employees>("Employee");
    
            Employees Employee = new Employees {EmployeeId=1,email="Marcos@fabrikam.com",name="Marcos"};
            mongoCollection.InsertOne (Employee);
    
            Employee = new Employees {EmployeeId=2,email="Tam@fabrikam.com",name="Tam"};
            mongoCollection.InsertOne (Employee);
    
            // return data where EmployeeId = 1
            Employees EmployeeFound =  mongoCollection.Find(_ => _.EmployeeId == 1).FirstOrDefault();
            Console.WriteLine ("Id: {0}, EmployeeId: {1}, email: \'{2}\', name: \'{3}\'", EmployeeFound.Id, EmployeeFound.EmployeeId, EmployeeFound.email, EmployeeFound.name);
        }
    }
    
  8. 讓我們繼續進行,並儲存程式。 選取程式碼編輯器的右上角,然後選取 [儲存] (或 [Ctrl+S])。 現在選取 [關閉編輯器] (或 Ctrl+Q) 以返回殼層。

  9. 現在讓我們使用下列命令來執行應用程式。

    node App.js
    
    mvn clean compile exec:java
    
    python App.py
    
    dotnet run
    
  10. 這應該會傳回與下列項目相似的結果。 這表示我們已建立資料庫、集合,並對其新增文件。

    {
      _id: new ObjectId("62aed08663c0fd62d30240db"),
      EmployeeId: 1,
      email: 'Marcos@fabrikam.com'
      name: 'Marcos'
    }
    
    INFO: Opened connection [connectionId{localValue:3, serverValue:2080122971}] to learn-account-cosmos-845083734-westus.mongo.cosmos.azure.com:10255
    { "_id" : { "$oid" : "62afd8e2c471f3011bd415fe" }, "EmployeeId" : 1, "email" : "Marcos@fabrikam.com", "name" : "Marcos" }
    Jun 20, 2022 2:18:11 AM com.mongodb.diagnostics.logging.JULLogger log
    INFO: Closed connection [connectionId{localValue:3, serverValue:2080122971}] to learn-account-cosmos-845083734-westus.mongo.cosmos.azure.com:10255 because the pool has been closed.
    
    {'_id': ObjectId('62afecc3a04e32b92451ac5d'), 'EmployeeId': 1, 'email': 'Marcos@fabrikan.com', 'name': 'Marcos'}
    
    Id: 62affed8147b5206db146298, EmployeeId: 1, email: 'Marcos@fabrikam.com', name: 'Marcos'
    
  11. 不過,最後這個結果集只會確認我們確實已建立資料庫、集合和文件,但分區金鑰和輸送量呢,其是否真的變更? 在 Cloud Shell 上,讓我們執行下列命令,以確認我們的變更是否生效。

    1. 讓我們確認分區金鑰已變更為 EmployeeId (預設值為 id)。 別忘了變更我們在此實驗室開頭所儲存名稱的 [資源群組名稱][帳戶名稱]

      az cosmosdb mongodb collection show --name Employee --database-name HumanResources --resource-group learn-20c8df29-1419-49f3-84bb-6613f052b5ae --account-name learn-account-cosmos-845083734
      

      結果應包含 "shardKey": {"EmployeeId": "Hash"} 屬性。

    2. 讓我們確認輸送量已變更為 1000 (預設值為 400)。 別忘了變更我們在此實驗室開頭所儲存名稱的 [資源群組名稱][帳戶名稱]

      az cosmosdb mongodb collection throughput show --name Employee --database-name HumanResources --resource-group learn-20c8df29-1419-49f3-84bb-6613f052b5ae --account-name learn-account-cosmos-845083734
      

      結果應該包含 "throughput": 1000 屬性。

此程式碼說明在我們程式碼中使用延伸命令的功能,這可讓我們定義 Azure Cosmos DB 建立參數。 這可讓我們利用控制 Azure Cosmos DB 建立及處理集合的方式。

在您完成此練習之後,請繼續進行本課程模組的知識檢定問題。