适用于 Azure Functions 2.x 及更高版本的 Azure Cosmos DB 触发器

Azure Cosmos DB 触发器使用 Azure Cosmos DB 更改源来侦听跨分区的插入和更新。 更改源发布新项和更新的项,不包括删除后的更新。 有关使用 Azure Cosmos DB 触发器的端到端方案,请参阅 快速入门:使用 Azure Functions 响应 Azure Cosmos DB 中的数据库更改

若要了解设置和配置详细信息,请参阅概述

面向消耗计划和高级计划的 Cosmos DB 缩放决策是通过基于目标的缩放完成的。 有关详细信息,请参阅基于目标的缩放

重要

本文使用选项卡来支持多个版本的 Node.js 编程模型。 v4 模型已正式发布,旨在为 JavaScript 和 TypeScript 开发人员提供更为灵活和直观的体验。 有关 v4 模型工作原理的更多详细信息,请参阅 Azure Functions Node.js 开发人员指南。 要详细了解 v3 和 v4 之间的差异,请参阅迁移指南

Azure Functions 支持两种 Python 编程模型。 定义绑定的方式取决于选择的编程模型。

使用 Python v2 编程模型,可以直接在 Python 函数代码中使用修饰器定义绑定。 有关详细信息,请参阅 Python 开发人员指南

本文同时支持两个编程模型。

有关使用 Azure Cosmos DB 触发器的完整端到端示例,请参阅使用 Azure FunctionsAzure Cosmos DB中的数据库更改。

示例

触发器的用法取决于扩展包版本,以及函数应用中使用的 C# 形式,可以是以下形式之一:

独立工作进程类库的已编译 C# 函数在独立于运行时的进程中运行。

以下示例取决于给定 C# 模式的扩展版本。

此示例使用应用设置引用并包括错误处理。 首先,定义模型类型:

public class ToDoItem
{
    public string? Id { get; set; }
    public string? Description { get; set; }
}

在指定的数据库和容器中插入或更新时,将运行以下函数:

[Function("CosmosTrigger")]
public void Run([CosmosDBTrigger(
    databaseName: "%COSMOS_DATABASE_NAME%",
    containerName: "%COSMOS_CONTAINER_NAME%",
    Connection = "COSMOS_CONNECTION",
    LeaseContainerName = "leases",
    CreateLeaseContainerIfNotExists = true)] IReadOnlyList<ToDoItem> documents,
    FunctionContext context)
{
    if (documents is not null && documents.Any())
    {
        _logger.LogInformation("Documents modified: {count}", documents.Count);
        foreach (var doc in documents)
        {
            try
            {
                _logger.LogInformation("Processing document Id: {id}", doc.Id);
                // Add your business logic here
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error processing document {id}", doc.Id);
                // Continue processing remaining documents
            }
        }
    }
}

[Function("health")]
public IActionResult HealthCheck([HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "health")] HttpRequest req)
{
    return new OkResult();
}

前面的示例使用应用设置引用(%VAR_NAME%)而不是硬编码的值。 有关配置详细信息,请参阅“进程内”选项卡中的应用设置和本地开发指南。

当指定数据库和容器中发生插入或更新操作时,会调用此函数。

由于 Azure Cosmos DB SDK 中的架构发生更改,Azure Cosmos DB 扩展的 4.x 版需要适用于 Java 函数的 azure-functions-java-library V3.0.0

    @FunctionName("CosmosDBTriggerFunction")
    public void run(
        @CosmosDBTrigger(
            name = "items",
            databaseName = "ToDoList",
            containerName = "Items",
            leaseContainerName="leases",
            connection = "AzureCosmosDBConnection",
            createLeaseContainerIfNotExists = true
        )
        Object inputItem,
        final ExecutionContext context
    ) {
        context.getLogger().info("Items modified: " + inputItems.size());
    }

Java 函数运行时库中,对值来自Azure Cosmos DB的参数使用 @CosmosDBTrigger 注释。 将此批注与本机Java类型、纯旧Java对象(POJO)或可通过使用 Optional<T>为 null 的值一起使用。

以下示例显示了 Azure Cosmos DB 触发器 TypeScript 函数。 添加或修改 Azure Cosmos DB 记录时,该函数会写入日志消息。

import { app, InvocationContext } from '@azure/functions';

export async function cosmosDBTrigger1(documents: unknown[], context: InvocationContext): Promise<void> {
    context.log(`Cosmos DB function processed ${documents.length} documents`);
}

app.cosmosDB('cosmosDBTrigger1', {
    connection: '<connection-app-setting>',
    databaseName: 'Tasks',
    containerName: 'Items',
    createLeaseContainerIfNotExists: true,
    handler: cosmosDBTrigger1,
});

以下示例显示了 Azure Cosmos DB 触发器 JavaScript 函数。 添加或修改 Azure Cosmos DB 记录时,该函数会写入日志消息。

const { app } = require('@azure/functions');

app.cosmosDB('cosmosDBTrigger1', {
    connection: '<connection-app-setting>',
    databaseName: 'Tasks',
    containerName: 'Items',
    createLeaseContainerIfNotExists: true,
    handler: (documents, context) => {
        context.log(`Cosmos DB function processed ${documents.length} documents`);
    },
});

下面的示例演示如何在 Azure Cosmos DB 中的数据更改时运行函数。

{
    "type": "cosmosDBTrigger",
    "name": "documents",
    "direction": "in",
    "leaseCollectionName": "leases",
    "connectionStringSetting": "<connection-app-setting>",
    "databaseName": "Tasks",
    "collectionName": "Items",
    "createLeaseCollectionIfNotExists": true
}

请注意,某些绑定属性名称在 Azure Cosmos DB 扩展的版本 4.x 中已更改。

run.ps1 文件中,可以通过 $Documents 参数访问触发函数的文档。

param($Documents, $TriggerMetadata) 

Write-Host "First document Id modified : $($Documents[0].id)" 

以下示例演示了 Azure Cosmos DB 触发器绑定。 该示例取决于使用的是 v1 还是 v2 Python 编程模型

import logging
import azure.functions as func

app = func.FunctionApp()

@app.function_name(name="CosmosDBTrigger")
@app.cosmos_db_trigger(arg_name="documents", 
                       database_name="%COSMOS_DATABASE_NAME%", 
                       container_name="%COSMOS_CONTAINER_NAME%",
                       connection="COSMOS_CONNECTION",
                       lease_container_name="leases",
                       create_lease_container_if_not_exists="true")
def cosmos_trigger(documents: func.DocumentList) -> str:
    if documents:
        for doc in documents:
            try:
                logging.info('Processing document id: %s', doc['id'])
                # Add your business logic here
            except Exception as e:
                logging.error('Error processing document %s: %s', doc.get('id', 'unknown'), str(e))
                # Continue processing remaining documents

@app.function_name(name="health")
@app.route(route="health", methods=["GET"])
def health_check(req: func.HttpRequest) -> func.HttpResponse:
    """Health check endpoint for monitoring."""
    return func.HttpResponse("OK", status_code=200)

前面的示例使用应用设置引用(%VAR_NAME%)而不是硬编码的值。

应用设置

为基于标识的连接配置以下应用程序设置:

设置 说明 示例
COSMOS_DATABASE_NAME Azure Cosmos DB数据库的名称 my-database
COSMOS_CONTAINER_NAME 要监视的容器的名称 my-container
COSMOS_CONNECTION__accountEndpoint Azure Cosmos DB帐户终结点 https://mycosmosdb.documents.azure.cn:443/
COSMOS_CONNECTION__credential 设置为 managedidentity UAMI managedidentity
COSMOS_CONNECTION__clientId 用户分配的托管标识的客户端 ID 00000000-0000-0000-0000-000000000000

本地开发

对于本地开发,请创建一个 local.settings.json 文件:

{
    "IsEncrypted": false,
    "Values": {
        "AzureWebJobsStorage": "UseDevelopmentStorage=true",
        "FUNCTIONS_WORKER_RUNTIME": "python",
        "COSMOS_DATABASE_NAME": "my-database",
        "COSMOS_CONTAINER_NAME": "my-container",
        "COSMOS_CONNECTION__accountEndpoint": "https://mycosmosdb.documents.azure.cn:443/"
    }
}

小窍门

对于本地开发,请省略 COSMOS_CONNECTION__credentialCOSMOS_CONNECTION__clientIdDefaultAzureCredential按顺序尝试多个凭据,包括Azure CLI登录凭据。

本地开发的先决条件:

特性

进程内独立进程 C# 库都用于CosmosDBTriggerAttribute定义函数。 C# 脚本改用 function.json 配置文件,如 C# 脚本指南中所述。

特定属性取决于进程模型和扩展版本:

独立工作进程库使用命名空间中的 Microsoft.Azure.Functions.Worker,该命名空间定义了以下属性:

Attribute 属性 说明
Connection 应用设置或设置集合的名称,用于指定如何连接到受监视的 Azure Cosmos DB 帐户。 有关详细信息,请参阅连接
DatabaseName 带有受监视的容器的 Azure Cosmos DB 数据库的名称。
ContainerName 要监视的容器的名称。
LeaseConnection (可选)应用设置或设置集合的名称,用于指定如何连接到保留租用容器的 Azure Cosmos DB 帐户。

未设置时,使用 Connection 值。 在门户中创建绑定时,将自动设置该参数。 用于租用容器的连接字符串必须具有写入权限。
LeaseDatabaseName (可选)数据库的名称,该数据库包含用于存储租用的容器。 未设置时,使用 databaseName 设置的值。
LeaseContainerName (可选)用于存储租约的容器的名称。 未设置时,使用值 leases
CreateLeaseContainerIfNotExists (可选)设置为 true 时,如果租用容器并不存在,将自动创建该集合。 默认值为 false。 在使用 Microsoft Entra 标识时,如果将值设为 true,则创建容器将不是允许的操作,并且无法启动函数。
LeasesContainerThroughput (可选)在创建租用容器时,定义要分配的请求单位的数量。 仅当 CreateLeaseContainerIfNotExists 设置为 true 时,才会使用此设置。 使用门户创建绑定时,将自动设置该参数。
LeaseContainerPrefix (可选)设置后,该值将作为前缀添加到在此函数的租用容器中创建的租约。 使用前缀可让两个不同的 Azure 函数通过不同的前缀来共享同一个租用容器。
FeedPollDelay (可选)在所有当前更改清空后,每两次在分区中轮询源上的新更改的延迟时间(以毫秒为单位)。 默认值为 5,000 毫秒(5 秒)。
LeaseAcquireInterval (可选)设置后,此项以毫秒为单位定义启动一个计算任务的时间间隔(前提是分区在已知的主机实例中均匀分布)。 默认为 13000(13 秒)。
LeaseExpirationInterval (可选)设置后,此项以毫秒为单位定义在表示分区的租用上进行租用的时间间隔。 如果在此时间间隔内不续订租用,则该租用会过期,分区的所有权会转移到另一个实例。 默认为 60000(60 秒)。
LeaseRenewInterval (可选)设置后,此项以毫秒为单位定义当前由实例拥有的分区的所有租用的续订时间间隔。 默认为 17000(17 秒)。
MaxItemsPerInvocation (可选)设置后,此属性会对每次函数调用收到的项目的最大数目进行设置。 如果受监视容器中的操作通过存储过程执行,则在从更改源读取项时,会保留事务范围。 因此,收到的项数可能高于指定的值,通过同一事务更改的项会通过某个原子批处理操作返回。
StartFromBeginning (可选)此选项告知触发器要从容器的更改历史记录开头位置读取更改,而不是从当前时间开始读取。 从开头位置读取仅在触发器首次启动时起作用,因为在后续运行中,已存储检查点。 如果已经创建租约,则将此选项设置为 true 将不起作用。
StartFromTime (可选)获取或设置初始化更改源读取操作的日期和时间。 建议使用具有 UTC 指示符的 ISO 8601 格式,例如 2021-02-16T14:19:29Z。 这仅用于设置初始触发器状态。 触发器具有租用状态后,更改此值将不起作用。
PreferredLocations (可选)为 Azure Cosmos DB 服务中的异地复制数据库帐户定义首选位置(区域)。 值应以逗号分隔。 例如,“中国北部,中国北部,中国北部”。

修饰符

仅适用于 Python v2 编程模型。

对于使用修饰器定义的 Python v2 函数,cosmos_db_trigger (Extension 4.x) 支持以下属性:

properties 说明
arg_name 函数代码中使用的变量名称,表示发生更改的文档列表。
database_name Azure Cosmos DB数据库的名称。 支持 %VAR_NAME% 引用应用设置的语法。
container_name 要监视的 Azure Cosmos DB 容器的名称。 支持 %VAR_NAME% 语法。
connection 基于标识的连接的应用设置或设置前缀的名称(例如解析 COSMOS_CONNECTIONCOSMOS_CONNECTION__accountEndpoint等)。
lease_container_name 用于存储租约的容器的名称。
create_lease_container_if_not_exists 如果 true不存在租约容器,则会自动创建租约容器。

对于使用 function.json 定义的 Python 函数,请参阅“配置”部分。

批注

由于 Azure Cosmos DB SDK 中的架构发生更改,Azure Cosmos DB 扩展的 4.x 版需要适用于 Java 函数的 azure-functions-java-library V3.0.0

对从 Azure Cosmos DB 读取数据的参数使用 @CosmosDBTrigger 注释。 此注释支持以下属性:

Attribute 属性 说明
连接 应用设置或设置集合的名称,用于指定如何连接到受监视的 Azure Cosmos DB 帐户。 有关详细信息,请参阅连接
name 函数的名称。
databaseName 带有受监视的容器的 Azure Cosmos DB 数据库的名称。
containerName 要监视的容器的名称。
leaseConnectionStringSetting (可选)应用设置或设置集合的名称,用于指定如何连接到保留租用容器的 Azure Cosmos DB 帐户。

未设置时,使用 Connection 值。 在门户中创建绑定时,将自动设置该参数。 用于租用容器的连接字符串必须具有写入权限。
leaseDatabaseName (可选)数据库的名称,该数据库包含用于存储租用的容器。 未设置时,使用 databaseName 设置的值。
leaseContainerName (可选)用于存储租约的容器的名称。 未设置时,使用值 leases
createLeaseContainerIfNotExists (可选)设置为 true 时,如果租用容器并不存在,将自动创建该集合。 默认值为 false。 如果将值 true设置为Microsoft Entra 标识,则创建容器不是 允许的作 ,并且不允许启动函数应用。
leasesContainerThroughput (可选)在创建租用容器时,定义要分配的请求单位的数量。 仅当 CreateLeaseContainerIfNotExists 设置为 true 时,才会使用此设置。 使用门户创建绑定时,将自动设置该参数。
leaseContainerPrefix (可选)设置后,该值将作为前缀添加到在此函数的租用容器中创建的租约。 使用前缀可让两个不同的 Azure 函数通过不同的前缀来共享同一个租用容器。
feedPollDelay (可选)在所有当前更改清空后,每两次在分区中轮询源上的新更改的延迟时间(以毫秒为单位)。 默认值为 5,000 毫秒(5 秒)。
leaseAcquireInterval (可选)设置后,此项以毫秒为单位定义启动一个计算任务的时间间隔(前提是分区在已知的主机实例中均匀分布)。 默认为 13000(13 秒)。
leaseExpirationInterval (可选)设置后,此项以毫秒为单位定义在表示分区的租用上进行租用的时间间隔。 如果未在此时间间隔内续订租约,则会过期,分区的所有权将移到另一个实例。 默认为 60000(60 秒)。
leaseRenewInterval (可选)设置后,它会定义实例当前持有的分区的所有租约的续订间隔(以毫秒为单位)。 默认为 17000(17 秒)。
maxItemsPerInvocation (可选)设置后,此属性会对每次函数调用收到的项目的最大数目进行设置。 如果受监视容器中的操作通过存储过程执行,则在从更改源读取项时,会保留事务范围。 因此,收到的项数可能高于指定的值,通过同一事务更改的项会通过某个原子批处理操作返回。
startFromBeginning (可选)此选项告知触发器要从容器的更改历史记录开头位置读取更改,而不是从当前时间开始读取。 从开头位置读取仅在触发器首次启动时起作用,因为在后续运行中,已存储检查点。 如果已经创建租约,则将此选项设置为 true 将不起作用。
preferredLocations (可选)为 Azure Cosmos DB 服务中的异地复制数据库帐户定义首选位置(区域)。 值应以逗号分隔。 例如“中国北部 2”。

配置

仅适用于 Python v1 编程模型

下表说明了可以在传递给options方法的对象上app.cosmosDB()设置的属性。 typedirectionname 属性不适用于 v4 模型。

下表解释了在 function.json 文件中设置的绑定配置属性,其中属性因扩展版本而异。

function.json 属性 说明
type 必须设置为 cosmosDBTrigger
direction 必须设置为 in。 在 Azure 门户中创建触发器时,会自动设置该参数。
name 函数代码中使用的变量名称,表示发生更改的文档列表。
连接 应用设置或设置集合的名称,用于指定如何连接到受监视的 Azure Cosmos DB 帐户。 有关详细信息,请参阅连接
databaseName 带有受监视的容器的 Azure Cosmos DB 数据库的名称。
containerName 要监视的容器的名称。
leaseConnection (可选)应用设置或设置容器的名称,用于指定如何连接到保留租用容器的 Azure Cosmos DB 帐户。

未设置时,使用 connection 值。 在门户中创建绑定时,将自动设置该参数。 用于租用容器的连接字符串必须具有写入权限。
leaseDatabaseName (可选)数据库的名称,该数据库包含用于存储租用的容器。 未设置时,使用 databaseName 设置的值。
leaseContainerName (可选)用于存储租约的容器的名称。 未设置时,使用值 leases
createLeaseContainerIfNotExists (可选)设置为 true 时,如果租用容器并不存在,将自动创建该集合。 默认值为 false。 在使用 Microsoft Entra 标识时,如果将值设为 true,则创建容器将不是允许的操作,并且无法启动函数。
leasesContainerThroughput (可选)在创建租用容器时,定义要分配的请求单位的数量。 仅当 createLeaseContainerIfNotExists 设置为 true 时,才会使用此设置。 使用门户创建绑定时,将自动设置该参数。
leaseContainerPrefix (可选)设置后,该值将作为前缀添加到在此函数的租用容器中创建的租约。 使用前缀可让两个不同的 Azure 函数通过不同的前缀来共享同一个租用容器。
feedPollDelay (可选)在所有当前更改清空后,每两次在分区中轮询源上的新更改的延迟时间(以毫秒为单位)。 默认值为 5,000 毫秒(5 秒)。
leaseAcquireInterval (可选)设置后,此项以毫秒为单位定义启动一个计算任务的时间间隔(前提是分区在已知的主机实例中均匀分布)。 默认为 13000(13 秒)。
leaseExpirationInterval (可选)设置后,此项以毫秒为单位定义在表示分区的租用上进行租用的时间间隔。 如果在此时间间隔内不续订租用,则该租用会过期,分区的所有权会转移到另一个实例。 默认为 60000(60 秒)。
leaseRenewInterval (可选)设置后,此项以毫秒为单位定义当前由实例拥有的分区的所有租用的续订时间间隔。 默认为 17000(17 秒)。
maxItemsPerInvocation (可选)设置后,此属性会对每次函数调用收到的项目的最大数目进行设置。 如果受监视容器中的操作通过存储过程执行,则在从更改源读取项时,会保留事务范围。 因此,收到的项数可能高于指定的值,通过同一事务更改的项会通过某个原子批处理操作返回。
startFromBeginning (可选)此选项告知触发器要从容器的更改历史记录开头位置读取更改,而不是从当前时间开始读取。 从开头位置读取仅在触发器首次启动时起作用,因为在后续运行中,已存储检查点。 如果已经创建租约,则将此选项设置为 true 将不起作用。
startFromTime (可选)获取或设置初始化更改源读取操作的日期和时间。 建议使用具有 UTC 指示符的 ISO 8601 格式,例如 2021-02-16T14:19:29Z。 这仅用于设置初始触发器状态。 触发器具有租用状态后,更改此值将不起作用。
preferredLocations (可选)为 Azure Cosmos DB 服务中的异地复制数据库帐户定义首选位置(区域)。 值应以逗号分隔。 例如,“中国北部,中国北部,中国北部”。

有关完整示例,请参阅 “示例”部分

使用情况

触发器需要第二个集合,该集合用于存储各分区的租用。 仅当监视的集合和包含租约的集合都可用时,触发器才有效。

重要

如果将多个函数配置为对同一集合使用Azure Cosmos DB触发器,则每个函数应使用专用租约集合或为每个函数指定不同的 LeaseCollectionPrefix。 否则,将只触发其中一个函数。 有关前缀的信息,请参阅“属性”部分

重要

如果将多个函数配置为对同一集合使用Azure Cosmos DB触发器,则每个函数应使用专用租约集合或为每个函数指定不同的 leaseCollectionPrefix。 否则,将只触发其中一个函数。 有关前缀的信息,请参阅“注释”部分

重要

如果将多个函数配置为对同一集合使用Azure Cosmos DB触发器,则每个函数应使用专用租约集合或为每个函数指定不同的 leaseCollectionPrefix。 否则,将只触发其中一个函数。 有关前缀的信息,请参阅“配置”部分

触发器不指示文档是更新还是插入文档。 它只是提供文档本身。 如果需要以不同的方式处理更新和插入,请实现插入或更新的时间戳字段。

Azure Cosmos DB 触发器支持的参数类型取决于 Functions 运行时版本、扩展包版本以及使用的 C# 模态。

如果你希望函数处理单个文档,可将 Cosmos DB 触发器绑定到以下类型:

类型 说明
JSON 可序列化类型 函数尝试将文档的 JSON 数据从 Cosmos DB 更改源反序列化为普通的旧 CLR 对象 (POCO) 类型。

如果你希望函数处理一批文档,可将 Cosmos DB 触发器绑定到以下类型:

类型 说明
IEnumerable<T>,其中 T 是 JSON 序列化的类型 批处理中包含的实体的枚举。 每个条目表示 Cosmos DB 更改源中的一个文档。

连接

connectionleaseConnection属性在应用设置中设置为键,返回函数运行时用于连接Azure Cosmos DB账户端点的数值。 这些属性设置的价值取决于连接类型:

  • 管理身份连接:该 connection 属性是由 <CONNECTION_NAME_PREFIX> 一组设置共享的,这些设置共同定义了基于身份的账户连接。 更多信息请参见 定义身份连接
  • 密钥保管库 引用connection属性设置返回一个 Azure 密钥保管库 引用,指向该 连接字符串 中心维护的位置。 更多信息请参见定义 密钥保管库 连接。
  • App Configuration 引用connection属性设置返回一个 Azure 应用程序配置 引用,返回一个 连接字符串 或 密钥保管库 引用。 更多信息请参见连接文章中的 Azure 应用程序配置
  • Connection string:属性设置返回connection实际账户的 连接字符串。 由于连接字符串包含共享的秘密密钥,你应尽量考虑使用管理身份连接。 更多信息请参见定义连接。

欲了解更多关于绑定连接的信息,请参见 Azure Functions 中的 Manage connection 。 要获取连接字符串,请进入你的Azure Cosmos DB账户,选择Keys,然后复制PRIMARY CONNECTION STRINGSECONDARY CONNECTION STRING的值。 这些连接字符串包含共享的秘密密钥,必须保持安全。

在扩展的早期版本中,连接性质被命名为 connectionStringSettingleaseConnectionStringSetting

后续步骤