练习 - 使用适用于 MongoDB 的 Azure Cosmos DB 创建 MongoDB DB 应用
是时候以编程方式了解如何创建 Azure Cosmos DB for MongoDB 数据库、集合,以及添加一些数据了。
可使用提供临时 Azure 订阅的 Microsoft Learn 沙盒完成本练习。 若要激活沙盒订阅,必须使用 Microsoft 帐户登录。 完成本模块后,沙盒订阅将自动删除。 激活沙盒后,请使用沙盒订阅的凭据登录 Azure 门户。 确保使用门户右上方的用户 ID 下显示的“Microsoft Learn 沙盒”目录。 如果没有,请选择用户图标并切换目录。
提示
如果愿意,你可以使用自己的 Azure 订阅。 为此,请使用订阅凭据登录 Azure 门户。 确保使用右上方用户 ID 下显示的包含订阅的目录。 如果没有,请选择用户图标并切换目录。
使用 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 数据库的方式代码相同。 然后,使用扩展命令创建集合,你可以通过这些命令以请求单位/秒 (RU) 为单位定义该集合的吞吐量。
准备开发环境
如果尚未准备好用于此实验室的 Azure Cosmos DB 帐户和环境,请按照以下步骤进行操作。 否则,请转至“将用于创建数据库、集合和文档的代码添加到 App.js 文件”部分。
如果尚未准备好用于此实验室的环境和 Azure Cosmos DB 帐户,请按照以下步骤进行操作。 否则,请转至“将用于创建数据库、集合和文档的代码添加到 App.java 文件”部分。
如果尚未准备好用于此实验室的 Azure Cosmos DB 帐户和环境,请按照以下步骤进行操作。 否则,请转至“将用于创建数据库、集合和文档的代码添加到 App.py 文件”部分。
如果尚未准备好用于此实验室的环境和 Azure Cosmos DB 帐户,请按照以下步骤进行操作。 否则,请转至“将用于创建数据库、集合和文档的代码添加到 app.cs 文件”部分。
在 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
提示
如果你不打算为实验室使用沙盒,并且需要指定要在其中创建数据库和存储对象的位置,请在 init.sh 调用中添加 -l LOCATIONNAME 参数。 此外,如果要指定资源组,请将 -r YOURRRESOURCEGROUPNAMEHERE 参数添加到 init.sh 调用。
注意
此 bash 脚本将创建 Azure Cosmos DB for MongoDB 帐户。 创建此帐户可能需要 5 - 10 分钟才能完成,不妨在此时喝杯咖啡或茶。
提示
如果你返回后发现 cloud shell 已重置,请在 cloud shell 中运行以下命令以使用 Node 版本 14,否则下一部分中的代码将失败。
- source ~/.nvm/nvm.sh
- nvm 安装 14.0.0
- npm 链接 mongodb
当 bash init.sh 文件完成运行时,将返回的“连接字符串”、“Cosmos DB 帐户名称”和“资源组名称”复制到某个位置,我们将在下一部分中用到它们。 还可以查看由位于连接字符串前面的帐户创建脚本返回的 JSON。 如果查看 JSON 中间的某个位置,应会看到 "kind": "MongoDB" 属性。
注意
请注意,也可使用 Azure 门户找到“连接字符串”、“Cosmos DB 帐户名称”和“资源组名称”。
将用于创建数据库、集合和文档的代码添加到 App.js 文件
现在是时候添加用于创建数据库、集合的 JavaScript 代码并向集合添加文档了。
将用于创建数据库、集合和文档的代码添加到 App.java 文件
现在是时候添加用于创建数据库、集合的 Java 代码并向集合添加文档了。
将用于创建数据库、集合和文档的代码添加到 App.py 文件
现在是时候添加用于创建数据库、集合的 Python 代码并向集合添加文档了。
将用于创建数据库、集合和文档的代码添加到 app.cs 文件
现在是时候添加用于创建数据库、集合的 C# 代码并向集合添加文档了。
打开 Azure Cloud Shell(如果尚未打开)。
运行以下命令以打开代码编辑器。
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
将以下代码复制到 App 文件。 不要忘记,你需要替换在上一部分中复制的连接字符串的 URL 值。
此部分代码使用 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);
下一步连接到产品数据库。 如果此数据库不存在,则只有在同一连接中或使用扩展命令创建集合时,才会创建该数据库。 将以下命令添加到编辑器中的脚本中。
// 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");
接下来,连接到文档集合(如果它已存在),然后将一个文档添加到该集合中。 如果集合不存在,则只有在同一连接中或使用扩展命令对该集合执行操作(例如,将文档添加到集合)时,此代码才会创建集合。 将以下命令添加到编辑器中的脚本中。
// 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);
现在,搜索插入的文档并将其显示到 shell。 将以下命令添加到编辑器中的脚本中。
// 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); } }
最后,关闭连接。 将以下命令添加到编辑器中的脚本中。
// 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.
脚本应如下所示:
// 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); } }
继续并保存该程序。 在代码编辑器的右上角选择“保存”(或 Ctrl+S)。 现在选择“关闭编辑器”(或 Ctrl+Q)以返回 Shell。
现在,使用以下命令运行该应用。
node App.js
mvn clean compile exec:java
python App.py
dotnet run
此脚本应该返回与以下内容类似的结果。 这意味着我们创建了数据库、集合,并向该集合添加了一个文档。
{ _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 帐户创建一个系统分配的托管标识。
- 在 Azure 门户中,导航到之前创建的 Azure Cosmos DB 帐户。
- 在左侧菜单的“设置”中,选择“标识”。
- 在“标识”窗格中,选择“系统分配”。
- 为“状态”选择“打开”。
- 选择“保存”。
- 创建托管标识需要一两分钟。
创建托管标识后,需要向托管标识分配必需的 Azure Cosmos DB 帐户权限。 使用 RBAC (基于角色的访问控制)分配托管标识所需的权限。 在本实验室中,我们将“参与者”角色分配给托管标识,以允许其从 Azure Cosmos DB 帐户读取数据以及向其中写入数据。 在生产环境中,应分配所需的最低特权角色。
- 在 Azure 门户中,导航到之前创建的 Azure Cosmos DB 帐户。
- 在左侧菜单的“设置”下,选择“访问控制(IAM)”。
- 依次选择“+ 添加”和“添加角色分配”。
- 在“特权管理员角色”下选择“参与者”,然后选择“下一步”。
- 在“成员”下选择“托管标识”,然后选择“+ 选择成员”。
- 在“选择托管标识”窗格中,搜索之前创建的托管标识,选择它,然后选择“查看 + 分配”。
现在,已将托管标识分配给具有必要权限的 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 客户端驱动程序与 Azure Cosmos DB 的 MongoDB API 进行通信。 可以按照 MongoDB 有线协议规定,通过适用于 MongoDB 的 Azure Cosmos DB API 来使用现有客户端驱动程序。
让我们创建一些用于创建集合并定义其分片键和吞吐量的代码。
打开 Azure Cloud Shell(如果尚未打开)。
运行以下命令以打开代码编辑器。
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
将以下代码复制到 文件。
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);
下一步连接到员工数据库。 如果此数据库不存在,则只有在同一连接中或使用扩展命令创建集合时,才会创建该数据库。 将以下命令添加到编辑器中的脚本中。
// 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");
到目前为止,它看起来类似于上一部分中的代码。 在这一步中,我们将利用扩展命令并创建自定义操作。 此操作允许我们定义集合的吞吐量和分片键。 反过来,该步骤为 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""}");
其余部分与前面的示例相同。 我们连接到该集合,插入一些行,最后查询并输出一行。 将以下命令添加到编辑器中的脚本中。
// 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); } }
脚本应如下所示:
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); } }
继续并保存该程序。 在代码编辑器的右上角选择“保存”(或 Ctrl+S)。 现在选择“关闭编辑器”(或 Ctrl+Q)以返回 Shell。
现在,使用以下命令运行该应用。
node App.js
mvn clean compile exec:java
python App.py
dotnet run
这应该返回与以下内容类似的结果。 这意味着我们创建了数据库、集合并向该集合添加了一个文档。
{ _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'
然而,最后一个结果集只证实了我们确实创建了数据库、集合和文档,但分片键和吞吐量是否真的发生了更改呢? 在 Cloud Shell 上,运行以下命令以验证更改是否生效。
验证分片键是否已更改为 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"} 属性。
验证一下吞吐量是否已更改为 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 创建和处理集合的方式。
完成此练习后,请继续做本模块的知识检查问题。