你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

使用 Azure Cosmos DB for MongoDB vCore 生成 Node.js 控制台应用

本指南可帮助你生成 Node.js 控制台应用程序,以连接到 Azure Cosmos DB for MongoDB vCore 群集。 准备开发环境,使用适用于 JavaScript 的 Azure SDK 中的 @azure/identity 包进行身份验证,并针对数据库中的文档执行常见操作。

先决条件

  • 现有的 Azure Cosmos DB for MongoDB (vCore) 群集。
  • 为群集配置了 Microsoft Entra 身份验证,已授予标识 dbOwner 角色。

  • Node 的最新长期支持 (LTS) 版本

配置控制台应用程序

接下来,创建新的控制台应用程序项目,并导入必要的库以向群集进行身份验证。

  1. 为项目创建新目录,并使用 npm init 初始化它。

    mkdir cosmos-mongodb-app
    cd cosmos-mongodb-app
    npm init -y
    
  2. 在项目中设置 TypeScript。

    npm install typescript ts-node @types/node --save-dev
    npx tsc --init
    
  3. 为应用程序创建主 app.ts TypeScript 文件。

    touch app.ts
    
  4. 安装用于身份验证的 @azure/identity 库。

    npm install @azure/identity
    
  5. 安装 mongodb 库。

    npm install mongodb
    

连接至群集

现在,使用 Azure.Identity 库获取用于连接到群集的 TokenCredential。 官方 MongoDB 驱动程序具有一个特殊接口,必须实现该接口,以便从 Microsoft Entra 获取令牌,以便在连接到群集时使用。

  1. 在 JavaScript 文件顶部导入必要的模块。

    import { MongoClient } from 'mongodb';
    import { DefaultAzureCredential } from '@azure/identity';
    
  2. 创建一个令牌回调函数,用于在需要时从 TokenCredential 实例获取令牌。

    const azureIdentityTokenCallback = async (_, credential) => {
        const tokenResponse = await credential.getToken(['https://ossrdbms-aad.database.windows.net/.default']);
    
        if (!tokenResponse || !tokenResponse.token) {
            throw new Error('Failed to retrieve a valid access token.');
        }
    
        return {
            accessToken: tokenResponse.token,
            expiresInSeconds: Math.floor((tokenResponse.expiresOnTimestamp - Date.now()) / 1000),
        };
    };
    
  3. 设置群集名称变量以连接到 Azure Cosmos DB for MongoDB vCore 群集。

    const clusterName = '<azure-cosmos-db-mongodb-vcore-cluster-name>';
    
  4. 创建DefaultAzureCredential实例。

    const credential = new DefaultAzureCredential();
    
  5. 创建配置了 OpenID Connect (OIDC) 身份验证的 MongoDB 客户端。

    client = new MongoClient(`mongodb+srv://${clusterName}.global.mongocluster.cosmos.azure.com/`, {
        connectTimeoutMS: 120000,
        tls: true,
        retryWrites: true,
        authMechanism: 'MONGODB-OIDC',
        authMechanismProperties: {
            OIDC_CALLBACK: (params) => azureIdentityTokenCallback(params, credential),
            ALLOWED_HOSTS: ['*.azure.com']
        }
    });
    
    console.log('Client created');
    
  1. 在 TypeScript 文件的顶部导入必要的模块。

    import { AccessToken, DefaultAzureCredential, TokenCredential } from '@azure/identity';
    import { Collection, Db, Filter, FindCursor, MongoClient, OIDCCallbackParams, OIDCResponse, UpdateFilter, UpdateOptions, UpdateResult, WithId } from 'mongodb';
    
  2. 创建一个令牌回调函数,用于在需要时从 TokenCredential 实例获取令牌。

    const AzureIdentityTokenCallback = async (params: OIDCCallbackParams, credential: TokenCredential): Promise<OIDCResponse> => {
        const tokenResponse: AccessToken | null = await credential.getToken(['https://ossrdbms-aad.database.windows.net/.default']);
        return {
            accessToken: tokenResponse?.token || '',
            expiresInSeconds: (tokenResponse?.expiresOnTimestamp || 0) - Math.floor(Date.now() / 1000)
        };
    };
    
  3. 设置群集名称变量以连接到 Azure Cosmos DB for MongoDB vCore 群集。

    const clusterName: string = '<azure-cosmos-db-mongodb-vcore-cluster-name>';
    
  4. 创建DefaultAzureCredential实例。

    const credential: TokenCredential = new DefaultAzureCredential();
    
  5. 创建配置了 OpenID Connect (OIDC) 身份验证的 MongoDB 客户端。

    const client = new MongoClient(
        `mongodb+srv://${clusterName}.global.mongocluster.cosmos.azure.com/`, {
        connectTimeoutMS: 120000,
        tls: true,
        retryWrites: true,
        authMechanism: 'MONGODB-OIDC',
        authMechanismProperties: {
            OIDC_CALLBACK: (params: OIDCCallbackParams) => AzureIdentityTokenCallback(params, credential),
            ALLOWED_HOSTS: ['*.azure.com']
        }
    });
    
    console.log('Client created');
    

执行常见操作

最后,使用官方库对数据库、集合和文档执行常见任务。 在这里,你将使用相同的类和方法与 MongoDB 或 DocumentDB 进行交互来管理集合和项。

  1. 按名称获取对数据库的引用。

    const databaseName = process.env.SETTINGS__DATABASENAME ?? 'cosmicworks';
    
    console.log('Database pointer created');
    
  2. 获取对集合的引用。

    const collectionName = process.env.SETTINGS__COLLECTIONNAME ?? 'products';
    
    console.log('Collection pointer created');
    
  3. 使用 collection.updateOne 创建文档,并将其更新插入到集合中。

    const filter = { _id: request.params._id };
    const payload = {
        $set: document
    };
    const options = {
        upsert: true
    };
    
    var response = await collection.updateOne(filter, payload, options);
    
    if (response.acknowledged) {
        console.log(`Documents upserted count:\t${response.matchedCount}`);
    }
    
  4. 从集合中获取特定文档时使用collection.findOne

    const filter = { _id: request.params.id };
    
    var document = await collection.findOne(filter, options);
    
    console.log(`Read document _id:\t${document._id}`);
    
  5. 使用 collection.find 查询匹配筛选条件的多个文档。

    var filter = {
        category: 'gear-surf-surfboards'
    };
    
    var documents = collection.find(filter);
    
    for await (const document of documents) {
        console.log(`Found document:\t${JSON.stringify(document)}`);
    }
    
  6. 完成后关闭 MongoDB 客户端连接。

    await client.close();
    
  1. 按名称获取对数据库的引用。

    const database: Db = client.db('<database-name>');
    
    console.log('Database pointer created');
    
  2. 获取对集合的引用。

    const collection: Collection<Product> = database.collection<Product>('<collection-name>');
    
    console.log('Collection pointer created');
    
  3. 定义表示产品文档的接口。

    interface Product {
        _id: string;
        category: string;
        name: string;
        quantity: number;
        price: number;
        clearance: boolean;
    }
    
  4. 使用 collection.updateOne 创建文档,并将其更新插入到集合中。

    var document: Product = {
        _id: 'aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb',
        category: 'gear-surf-surfboards',
        name: 'Yamba Surfboard',
        quantity: 12,
        price: 850.00,
        clearance: false
    };
    
    var query: Filter<Product> = {
        _id: 'aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb'
    };
    var payload: UpdateFilter<Product> = {
        $set: document
    };
    var options: UpdateOptions = {
        upsert: true
    };
    var response: UpdateResult<Product> = await collection.updateOne(query, payload, options);
    
    if (response.acknowledged) {
        console.log(`Documents upserted count:\t${response.matchedCount}`);
    }
    
  5. 从集合中获取特定文档时使用collection.findOne

    var query: Filter<Product> = {
        _id: 'aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb',
        category: 'gear-surf-surfboards'
    };
    
    var response: WithId<Product> | null = await collection.findOne(query);
    
    var read_item: Product = response as Product;
    
    console.log(`Read document _id:\t${read_item._id}`);
    
  6. 使用 collection.find 查询匹配筛选条件的多个文档。

    var query: Filter<Product> = {
        category: 'gear-surf-surfboards'
    };
    
    var response: FindCursor<WithId<Product>> = collection.find(query);
    
    for await (const document of response) {
        console.log(`Found document:\t${JSON.stringify(document)}`);
    }
    
  7. 完成后关闭 MongoDB 客户端连接。

    await client.close();