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

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

Azure Cosmos DB 触发器使用 Azure Cosmos DB 更改源来侦听跨分区的插入和更新。 更改源发布新项和更新的项,不包括删除后的更新。

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

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

重要

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

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

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

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

示例

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

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

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

此示例引用简单的 ToDoItem 类型:

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

当指定数据库和集合中发生插入或更新操作时,会调用以下函数。

[Function("CosmosTrigger")]
public void Run([CosmosDBTrigger(
    databaseName: "ToDoItems",
    containerName:"TriggerItems",
    Connection = "CosmosDBConnection",
    LeaseContainerName = "leases",
    CreateLeaseContainerIfNotExists = true)] IReadOnlyList<ToDoItem> todoItems,
    FunctionContext context)
{
    if (todoItems is not null && todoItems.Any())
    {
        foreach (var doc in todoItems)
        {
            _logger.LogInformation("ToDoItem: {desc}", doc.Description);
        }
    }
}

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

由于 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 函数运行时库中,对其值将来自 Cosmos DB 的参数使用 @CosmosDBTrigger 注释。 可以将此注释与本机 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(name="documents", 
                       connection="CONNECTION_SETTING",
                       database_name="DB_NAME", 
                       container_name="CONTAINER_NAME", 
                       lease_container_name="leases",
                       create_lease_container_if_not_exists="true")
def test_function(documents: func.DocumentList) -> str:
    if documents:
        logging.info('Document id: %s', documents[0]['id'])

特性

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

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 上的以下属性:

properties 说明
arg_name 函数代码中使用的变量名称,表示发生更改的文档列表。
database_name 带有受监视的集合的 Azure Cosmos DB 数据库的名称。
collection_name 受到监视的 Azure Cosmos DB 集合的名称。
connection 受到监视的 Azure Cosmos DB 的连接字符串。

对于使用 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。 使用 Microsoft Entra 标识时,如果将值设置为 true,则创建容器不是允许的操作,并且函数不会启动。
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 服务中的异地复制数据库帐户定义首选位置(区域)。 值应以逗号分隔。 例如,“美国东部,美国中南部,北欧”。

配置

仅适用于 Python v1 编程模型

下表说明了可以在传递给方法“app.cosmosDB()”的对象“options”上设置的属性。 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 更改源中的一个文档。

连接

connectionStringSetting/connectionleaseConnectionStringSetting/leaseConnection 属性是对指定应用应该如何连接到 Azure Cosmos DB 的环境配置的引用。 这些属性可以指定:

如果配置的值既是单个设置的完全匹配,也是其他设置的前缀匹配,则使用完全匹配。

连接字符串

数据库帐户的连接字符串应存储在应用程序设置中,其名称与绑定配置的 connection 属性指定的值匹配。

基于标识的连接

如果使用版本 4.x 或更高版本的扩展,而不是结合使用连接字符串与机密,则可以要求应用使用 Microsoft Entra 标识。 为此,需要定义公共前缀下的设置,该前缀映射到触发器和绑定配置中的 connection 属性。

在此模式下,扩展需要以下属性:

属性 环境变量模板 说明 示例值
帐户终结点 <CONNECTION_NAME_PREFIX>__accountEndpoint Azure Cosmos DB 帐户终结点 URI。 https://<database_account_name>.documents.azure.com:443/

可以设置其他属性来自定义连接。 请参阅基于标识的连接的通用属性

在 Azure Functions 服务中托管时,基于标识的连接将使用托管标识。 默认情况下使用系统分配的标识,但可以使用 credentialclientID 属性来指定用户分配的标识。 请注意,不支持为用户分配的标识配置资源 ID。 在其他上下文(如本地开发)中运行时,将改用开发人员标识,尽管可以进行自定义。 请参阅使用基于标识的连接进行本地开发

向标识授予权限

无论使用何种标识,都必须具有执行所需操作的权限。 对于大多数 Azure 服务,这意味着你需要使用内置角色或者提供这些权限的自定义角色在 Azure RBAC 中分配角色

重要

某些权限可能由并非所有上下文都需要的目标服务公开。 尽可能遵循最低权限原则,仅授予标识所需的权限。 例如,如果应用只需要从数据源进行读取即可,则使用仅具有读取权限的角色。 分配一个也具有该服务写入权限的角色并不恰当,因为对于读取操作来说,写入是多余的权限。 同样,你也希望确保角色分配的范围仅限于需要读取的资源。

Cosmos DB 不使用 Azure RBAC 进行数据操作, 而是使用基于类似概念构建的 Cosmos DB 内置 RBAC 系统。 你将需要创建一个角色分配,以便在运行时提供对数据库帐户的访问权限。 所有者之类的 Azure RBAC 管理角色还不够。 下表显示了在正常操作中使用 Azure Cosmos DB 扩展时建议使用的内置角色。 根据所编写的代码,应用程序可能需要具有其他权限。

绑定类型 示例内置角色1
触发器2 Cosmos DB 内置数据参与者
输入绑定 Cosmos DB 内置数据读取者
输出绑定 Cosmos DB 内置数据参与者

1 这些角色不能在 Azure RBAC 角色分配中使用。 请参阅 Cosmos DB 内置 RBAC 系统文档,详细了解如何分配这些角色。

2 使用标识时,Cosmos DB 将容器创建视为管理操作。 它不可用作触发器的数据平面操作。 在设置函数之前,需确保创建触发器所需的容器(包括租用容器)。

后续步骤