Compartir a través de

适用于 Azure Functions 2.x 及更高版本的 Azure Cosmos DB 输入绑定

Azure Cosmos DB 输入绑定会使用 SQL API 检索一个或多个 Azure Cosmos DB 文档,并将其传递给函数的输入参数。 可根据调用函数的触发器确定文档 ID 或查询参数。

有关设置和配置详细信息,请参阅概述

注意

当集合已分区时,查找操作还必须指定分区键值。

重要

本文使用选项卡来支持多个版本的 Node.js 编程模型。 v4 模型目前处于预览状态,旨在为 JavaScript 和 TypeScript 开发人员提供更为灵活和直观的体验。 在升级指南中详细了解 v3 和 v4 之间的差异。

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

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

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

示例

除非另有说明,否则本文中的示例针对的都是 Azure Cosmos DB 扩展的版本 3.x。 若要与扩展版本 4.x 一起使用,需要将 collection 属性和属性名称中的字符串替换为 container

可以使用以下 C# 模式之一创建 C# 函数:

  • 进程内类库:编译的 C# 函数,该函数在与 Functions 运行时相同的进程中运行。
  • 独立工作进程类库:编译的 C# 函数,该函数在独立于运行时的工作进程中运行。 需要独立的工作进程才能支持在非 LTS 版 .NET 和 .NET Framework 上运行的 C# 函数。
  • C# 脚本:主要在 Azure 门户中创建 C# 函数时使用。

本部分包含需要 3.x 版 Azure Cosmos DB 扩展和 5.x 版 Azure 存储扩展的示例。 如果你的函数应用中尚不存在对以下 NuGet 包的引用,请添加它们:

这些示例引用简单的 ToDoItem 类型:

        [Function(nameof(DocByIdFromJSON))]
        public void DocByIdFromJSON(
            [QueueTrigger("todoqueueforlookup")] ToDoItemLookup toDoItemLookup,
            [CosmosDBInput(
                databaseName: "ToDoItems",
                containerName: "Items",
                Connection  = "CosmosDBConnection",
                Id = "{ToDoItemId}",
                PartitionKey = "{ToDoItemPartitionKeyValue}")] ToDoItem toDoItem)
        {
            _logger.LogInformation($"C# Queue trigger function processed Id={toDoItemLookup?.ToDoItemId} Key={toDoItemLookup?.ToDoItemPartitionKeyValue}");

            if (toDoItem == null)
            {
                _logger.LogInformation($"ToDo item not found");
            }
            else
            {
                _logger.LogInformation($"Found ToDo item, Description={toDoItem.Description}");
            }
        }

队列触发器,从 JSON 查找 ID

以下示例显示了一个检索单个文档的函数。 该函数由存储队列中的 JSON 消息触发。 队列触发器将 JSON 分析为 ToDoItemLookup 类型的对象,其中包含要检索的 ID 和分区键值。 该 ID 和分区键值用于从指定的数据库和集合中返回一个 ToDoItem 文档。

        [Function(nameof(DocByIdFromJSON))]
        public void DocByIdFromJSON(
            [QueueTrigger("todoqueueforlookup")] ToDoItemLookup toDoItemLookup,
            [CosmosDBInput(
                databaseName: "ToDoItems",
                containerName: "Items",
                Connection  = "CosmosDBConnection",
                Id = "{ToDoItemId}",
                PartitionKey = "{ToDoItemPartitionKeyValue}")] ToDoItem toDoItem)
        {
            _logger.LogInformation($"C# Queue trigger function processed Id={toDoItemLookup?.ToDoItemId} Key={toDoItemLookup?.ToDoItemPartitionKeyValue}");

            if (toDoItem == null)
            {
                _logger.LogInformation($"ToDo item not found");
            }
            else
            {
                _logger.LogInformation($"Found ToDo item, Description={toDoItem.Description}");
            }
        }

本部分包含以下示例:

这些示例引用简单的 ToDoItem 类型:

public class ToDoItem {

  private String id;
  private String description;

  public String getId() {
    return id;
  }

  public String getDescription() {
    return description;
  }

  @Override
  public String toString() {
    return "ToDoItem={id=" + id + ",description=" + description + "}";
  }
}

HTTP 触发器,从查询字符串查找 ID - 字符串参数

以下示例展示了检索单个文档的 Java 函数。 此函数由 HTTP 请求触发,该请求使用的查询字符串用于指定要查找的 ID 和分区键值。 该 ID 和分区键值用于以字符串形式从指定的数据库和集合中检索文档。

public class DocByIdFromQueryString {

    @FunctionName("DocByIdFromQueryString")
    public HttpResponseMessage run(
            @HttpTrigger(name = "req",
              methods = {HttpMethod.GET, HttpMethod.POST},
              authLevel = AuthorizationLevel.ANONYMOUS)
            HttpRequestMessage<Optional<String>> request,
            @CosmosDBInput(name = "database",
              databaseName = "ToDoList",
              collectionName = "Items",
              id = "{Query.id}",
              partitionKey = "{Query.partitionKeyValue}",
              connectionStringSetting = "Cosmos_DB_Connection_String")
            Optional<String> item,
            final ExecutionContext context) {

        // Item list
        context.getLogger().info("Parameters are: " + request.getQueryParameters());
        context.getLogger().info("String from the database is " + (item.isPresent() ? item.get() : null));

        // Convert and display
        if (!item.isPresent()) {
            return request.createResponseBuilder(HttpStatus.BAD_REQUEST)
                          .body("Document not found.")
                          .build();
        }
        else {
            // return JSON from Cosmos. Alternatively, we can parse the JSON string
            // and return an enriched JSON object.
            return request.createResponseBuilder(HttpStatus.OK)
                          .header("Content-Type", "application/json")
                          .body(item.get())
                          .build();
        }
    }
}

Java 函数运行时库中,对其值将来自 Azure Cosmos DB 的函数参数使用 @CosmosDBInput 注释。 可以将此注释与本机 Java 类型、POJO 或使用了 Optional<T> 的可为 null 的值一起使用。

HTTP 触发器,从查询字符串查找 ID - POJO 参数

以下示例展示了检索单个文档的 Java 函数。 此函数由 HTTP 请求触发,该请求使用的查询字符串用于指定要查找的 ID 和分区键值。 该 ID 和分区键值用于从指定的数据库和集合中检索文档。 然后将该文档转换为先前创建的 ToDoItem POJO 实例,并作为参数传递给该函数。

public class DocByIdFromQueryStringPojo {

    @FunctionName("DocByIdFromQueryStringPojo")
    public HttpResponseMessage run(
            @HttpTrigger(name = "req",
              methods = {HttpMethod.GET, HttpMethod.POST},
              authLevel = AuthorizationLevel.ANONYMOUS)
            HttpRequestMessage<Optional<String>> request,
            @CosmosDBInput(name = "database",
              databaseName = "ToDoList",
              collectionName = "Items",
              id = "{Query.id}",
              partitionKey = "{Query.partitionKeyValue}",
              connectionStringSetting = "Cosmos_DB_Connection_String")
            ToDoItem item,
            final ExecutionContext context) {

        // Item list
        context.getLogger().info("Parameters are: " + request.getQueryParameters());
        context.getLogger().info("Item from the database is " + item);

        // Convert and display
        if (item == null) {
            return request.createResponseBuilder(HttpStatus.BAD_REQUEST)
                          .body("Document not found.")
                          .build();
        }
        else {
            return request.createResponseBuilder(HttpStatus.OK)
                          .header("Content-Type", "application/json")
                          .body(item)
                          .build();
        }
    }
}

HTTP 触发器,从路由数据查找 ID

以下示例展示了检索单个文档的 Java 函数。 此函数由 HTTP 请求触发,该请求使用的路由参数用于指定要查找的 ID 和分区键值。 该 ID 和分区键值用于从指定的数据库和集合中检索文档,将它作为 Optional<String> 返回。

public class DocByIdFromRoute {

    @FunctionName("DocByIdFromRoute")
    public HttpResponseMessage run(
            @HttpTrigger(name = "req",
              methods = {HttpMethod.GET, HttpMethod.POST},
              authLevel = AuthorizationLevel.ANONYMOUS,
              route = "todoitems/{partitionKeyValue}/{id}")
            HttpRequestMessage<Optional<String>> request,
            @CosmosDBInput(name = "database",
              databaseName = "ToDoList",
              collectionName = "Items",
              id = "{id}",
              partitionKey = "{partitionKeyValue}",
              connectionStringSetting = "Cosmos_DB_Connection_String")
            Optional<String> item,
            final ExecutionContext context) {

        // Item list
        context.getLogger().info("Parameters are: " + request.getQueryParameters());
        context.getLogger().info("String from the database is " + (item.isPresent() ? item.get() : null));

        // Convert and display
        if (!item.isPresent()) {
            return request.createResponseBuilder(HttpStatus.BAD_REQUEST)
                          .body("Document not found.")
                          .build();
        }
        else {
            // return JSON from Cosmos. Alternatively, we can parse the JSON string
            // and return an enriched JSON object.
            return request.createResponseBuilder(HttpStatus.OK)
                          .header("Content-Type", "application/json")
                          .body(item.get())
                          .build();
        }
    }
}

HTTP 触发器,使用 SqlQuery 从路由数据查找 ID

以下示例展示了检索单个文档的 Java 函数。 此函数由 HTTP 请求触发,该请求使用路由参数指定要查找的 ID。 该 ID 用于从指定的数据库和集合中检索文档,将结果集转换为 ToDoItem[],因为可能会返回许多文档,具体取决于查询条件。

注意

如果需要只按 ID 进行查询,则建议使用查找(如以前的示例所示),因为该查找消耗较少的请求单位。 点读取操作 (GET) 比按 ID 进行的查询更高效

public class DocByIdFromRouteSqlQuery {

    @FunctionName("DocByIdFromRouteSqlQuery")
    public HttpResponseMessage run(
            @HttpTrigger(name = "req",
              methods = {HttpMethod.GET, HttpMethod.POST},
              authLevel = AuthorizationLevel.ANONYMOUS,
              route = "todoitems2/{id}")
            HttpRequestMessage<Optional<String>> request,
            @CosmosDBInput(name = "database",
              databaseName = "ToDoList",
              collectionName = "Items",
              sqlQuery = "select * from Items r where r.id = {id}",
              connectionStringSetting = "Cosmos_DB_Connection_String")
            ToDoItem[] item,
            final ExecutionContext context) {

        // Item list
        context.getLogger().info("Parameters are: " + request.getQueryParameters());
        context.getLogger().info("Items from the database are " + item);

        // Convert and display
        if (item == null) {
            return request.createResponseBuilder(HttpStatus.BAD_REQUEST)
                          .body("Document not found.")
                          .build();
        }
        else {
            return request.createResponseBuilder(HttpStatus.OK)
                          .header("Content-Type", "application/json")
                          .body(item)
                          .build();
        }
    }
}

HTTP 触发器,使用 SqlQuery 从路由数据获取多个文档

以下示例演示了检索多个文档的 Java 函数。 该函数由 HTTP 请求触发,该请求使用路由参数 desc 指定要在 description 字段中搜索的字符串。 搜索项用于从指定的数据库和集合中检索文档集合,将结果集转换为 ToDoItem[] 并将其作为参数传递给函数。

public class DocsFromRouteSqlQuery {

    @FunctionName("DocsFromRouteSqlQuery")
    public HttpResponseMessage run(
            @HttpTrigger(name = "req",
              methods = {HttpMethod.GET},
              authLevel = AuthorizationLevel.ANONYMOUS,
              route = "todoitems3/{desc}")
            HttpRequestMessage<Optional<String>> request,
            @CosmosDBInput(name = "database",
              databaseName = "ToDoList",
              collectionName = "Items",
              sqlQuery = "select * from Items r where contains(r.description, {desc})",
              connectionStringSetting = "Cosmos_DB_Connection_String")
            ToDoItem[] items,
            final ExecutionContext context) {

        // Item list
        context.getLogger().info("Parameters are: " + request.getQueryParameters());
        context.getLogger().info("Number of items from the database is " + (items == null ? 0 : items.length));

        // Convert and display
        if (items == null) {
            return request.createResponseBuilder(HttpStatus.BAD_REQUEST)
                          .body("No documents found.")
                          .build();
        }
        else {
            return request.createResponseBuilder(HttpStatus.OK)
                          .header("Content-Type", "application/json")
                          .body(items)
                          .build();
        }
    }
}

此部分包含的以下示例可以通过指定各种源提供的 ID 值来读取单个文档:

队列触发器,从 JSON 查找 ID

下面的示例演示 TypeScript 函数,该函数读取单个文档并更新文档的文本值。

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

const cosmosInput = input.cosmosDB({
    databaseName: 'MyDatabase',
    collectionName: 'MyCollection',
    id: '{queueTrigger}',
    partitionKey: '{queueTrigger}',
    connectionStringSetting: 'MyAccount_COSMOSDB',
});

const cosmosOutput = output.cosmosDB({
    databaseName: 'MyDatabase',
    collectionName: 'MyCollection',
    createIfNotExists: false,
    partitionKey: '{queueTrigger}',
    connectionStringSetting: 'MyAccount_COSMOSDB',
});

interface MyDocument {
    text: string;
}

export async function storageQueueTrigger1(queueItem: unknown, context: InvocationContext): Promise<void> {
    const doc = <MyDocument>context.extraInputs.get(cosmosInput);
    doc.text = 'This was updated!';
    context.extraOutputs.set(cosmosOutput, doc);
}

app.storageQueue('storageQueueTrigger1', {
    queueName: 'outqueue',
    connection: 'MyStorageConnectionAppSetting',
    extraInputs: [cosmosInput],
    extraOutputs: [cosmosOutput],
    handler: storageQueueTrigger1,
});

HTTP 触发器,从查询字符串查找 ID

以下示例演示检索单个文档的 TypeScript 函数。 此函数由 HTTP 请求触发,该请求使用的查询字符串用于指定要查找的 ID 和分区键值。 该 ID 和分区键值用于从指定的数据库和集合中检索 ToDoItem 文档。

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

const cosmosInput = input.cosmosDB({
    databaseName: 'ToDoItems',
    collectionName: 'Items',
    id: '{Query.id}',
    partitionKey: '{Query.partitionKeyValue}',
    connectionStringSetting: 'CosmosDBConnection',
});

interface ToDoDocument {
    description: string;
}

export async function httpTrigger1(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> {
    const toDoItem = <ToDoDocument>context.extraInputs.get(cosmosInput);
    if (!toDoItem) {
        return {
            status: 404,
            body: 'ToDo item not found',
        };
    } else {
        return {
            body: `Found ToDo item, Description=${toDoItem.description}`,
        };
    }
}

app.http('httpTrigger1', {
    methods: ['GET', 'POST'],
    authLevel: 'anonymous',
    extraInputs: [cosmosInput],
    handler: httpTrigger1,
});

HTTP 触发器,从路由数据查找 ID

以下示例演示检索单个文档的 TypeScript 函数。 此函数由 HTTP 请求触发,该请求使用的路由数据用于指定要查找的 ID 和分区键值。 该 ID 和分区键值用于从指定的数据库和集合中检索 ToDoItem 文档。

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

const cosmosInput = input.cosmosDB({
    databaseName: 'ToDoItems',
    collectionName: 'Items',
    id: '{id}',
    partitionKey: '{partitionKeyValue}',
    connectionStringSetting: 'CosmosDBConnection',
});

interface ToDoDocument {
    description: string;
}

export async function httpTrigger1(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> {
    const toDoItem = <ToDoDocument>context.extraInputs.get(cosmosInput);
    if (!toDoItem) {
        return {
            status: 404,
            body: 'ToDo item not found',
        };
    } else {
        return {
            body: `Found ToDo item, Description=${toDoItem.description}`,
        };
    }
}

app.http('httpTrigger1', {
    methods: ['GET', 'POST'],
    authLevel: 'anonymous',
    route: 'todoitems/{partitionKeyValue}/{id}',
    extraInputs: [cosmosInput],
    handler: httpTrigger1,
});

队列触发器,使用 SqlQuery 获取多个文档

以下示例演示了一个 TypeScript 函数,该函数使用队列触发器来自定义查询参数,以检索 SQL 查询指定的多个文档。

队列触发器提供参数 departmentId{ "departmentId" : "Finance" } 的队列消息将返回财务部的所有记录。

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

const cosmosInput = input.cosmosDB({
    databaseName: 'MyDb',
    collectionName: 'MyCollection',
    sqlQuery: 'SELECT * from c where c.departmentId = {departmentId}',
    connectionStringSetting: 'CosmosDBConnection',
});

interface MyDocument {}

export async function storageQueueTrigger1(queueItem: unknown, context: InvocationContext): Promise<void> {
    const documents = <MyDocument[]>context.extraInputs.get(cosmosInput);
    for (const document of documents) {
        // operate on each document
    }
}

app.storageQueue('storageQueueTrigger1', {
    queueName: 'outqueue',
    connection: 'MyStorageConnectionAppSetting',
    extraInputs: [cosmosInput],
    handler: storageQueueTrigger1,
});

此部分包含的以下示例可以通过指定各种源提供的 ID 值来读取单个文档:

队列触发器,从 JSON 查找 ID

以下示例演示了一个 JavaScript 函数,该函数读取单个文档并更新文档的文本值。

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

const cosmosInput = input.cosmosDB({
    databaseName: 'MyDatabase',
    collectionName: 'MyCollection',
    id: '{queueTrigger}',
    partitionKey: '{queueTrigger}',
    connectionStringSetting: 'MyAccount_COSMOSDB',
});

const cosmosOutput = output.cosmosDB({
    databaseName: 'MyDatabase',
    collectionName: 'MyCollection',
    createIfNotExists: false,
    partitionKey: '{queueTrigger}',
    connectionStringSetting: 'MyAccount_COSMOSDB',
});

app.storageQueue('storageQueueTrigger1', {
    queueName: 'outqueue',
    connection: 'MyStorageConnectionAppSetting',
    extraInputs: [cosmosInput],
    extraOutputs: [cosmosOutput],
    handler: (queueItem, context) => {
        const doc = context.extraInputs.get(cosmosInput);
        doc.text = 'This was updated!';
        context.extraOutputs.set(cosmosOutput, doc);
    },
});

HTTP 触发器,从查询字符串查找 ID

以下示例演示检索单个文档的 JavaScript 函数。 此函数由 HTTP 请求触发,该请求使用的查询字符串用于指定要查找的 ID 和分区键值。 该 ID 和分区键值用于从指定的数据库和集合中检索 ToDoItem 文档。

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

const cosmosInput = input.cosmosDB({
    databaseName: 'ToDoItems',
    collectionName: 'Items',
    id: '{Query.id}',
    partitionKey: '{Query.partitionKeyValue}',
    connectionStringSetting: 'CosmosDBConnection',
});

app.http('httpTrigger1', {
    methods: ['GET', 'POST'],
    authLevel: 'anonymous',
    extraInputs: [cosmosInput],
    handler: (request, context) => {
        const toDoItem = context.extraInputs.get(cosmosInput);
        if (!toDoItem) {
            return {
                status: 404,
                body: 'ToDo item not found',
            };
        } else {
            return {
                body: `Found ToDo item, Description=${toDoItem.Description}`,
            };
        }
    },
});

HTTP 触发器,从路由数据查找 ID

以下示例演示检索单个文档的 JavaScript 函数。 此函数由 HTTP 请求触发,该请求使用的路由数据用于指定要查找的 ID 和分区键值。 该 ID 和分区键值用于从指定的数据库和集合中检索 ToDoItem 文档。

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

const cosmosInput = input.cosmosDB({
    databaseName: 'ToDoItems',
    collectionName: 'Items',
    id: '{id}',
    partitionKey: '{partitionKeyValue}',
    connectionStringSetting: 'CosmosDBConnection',
});

app.http('httpTrigger1', {
    methods: ['GET', 'POST'],
    authLevel: 'anonymous',
    route: 'todoitems/{partitionKeyValue}/{id}',
    extraInputs: [cosmosInput],
    handler: (request, context) => {
        const toDoItem = context.extraInputs.get(cosmosInput);
        if (!toDoItem) {
            return {
                status: 404,
                body: 'ToDo item not found',
            };
        } else {
            return {
                body: `Found ToDo item, Description=${toDoItem.Description}`,
            };
        }
    },
});

队列触发器,使用 SqlQuery 获取多个文档

以下示例演示了一个 JavaScript 函数,该函数使用队列触发器自定义查询参数来检索 SQL 查询指定的多个文档。

队列触发器提供参数 departmentId{ "departmentId" : "Finance" } 的队列消息将返回财务部的所有记录。

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

const cosmosInput = input.cosmosDB({
    databaseName: 'MyDb',
    collectionName: 'MyCollection',
    sqlQuery: 'SELECT * from c where c.departmentId = {departmentId}',
    connectionStringSetting: 'CosmosDBConnection',
});

app.storageQueue('storageQueueTrigger1', {
    queueName: 'outqueue',
    connection: 'MyStorageConnectionAppSetting',
    extraInputs: [cosmosInput],
    handler: (queueItem, context) => {
        const documents = context.extraInputs.get(cosmosInput);
        for (const document of documents) {
            // operate on each document
        }
    },
});

队列触发器,从 JSON 查找 ID

下面的示例演示如何读取和更新单个 Azure Cosmos DB 文档。 文档的唯一标识符通过队列消息中的 JSON 值提供。

Azure Cosmos DB 输入绑定在函数配置文件 (function.json) 中提供的绑定列表中首先列出。

{
  "name": "InputDocumentIn",
  "type": "cosmosDB",
  "databaseName": "MyDatabase",
  "collectionName": "MyCollection",
  "id": "{queueTrigger_payload_property}",
  "partitionKey": "{queueTrigger_payload_property}",
  "connectionStringSetting": "CosmosDBConnection",
  "direction": "in"
},
{
  "name": "InputDocumentOut",
  "type": "cosmosDB",
  "databaseName": "MyDatabase",
  "collectionName": "MyCollection",
  "createIfNotExists": false,
  "partitionKey": "{queueTrigger_payload_property}",
  "connectionStringSetting": "CosmosDBConnection",
  "direction": "out"
}

run.ps1 文件包含 PowerShell 代码,该代码读取传入的文档并输出更改。

param($QueueItem, $InputDocumentIn, $TriggerMetadata)

$Document = $InputDocumentIn 
$Document.text = 'This was updated!'

Push-OutputBinding -Name InputDocumentOut -Value $Document  

HTTP 触发器,从查询字符串查找 ID

下面的示例演示如何通过 Web API 读取和更新单个 Azure Cosmos DB 文档。 文档的唯一标识符通过 HTTP 请求中的 querystring 参数提供,如绑定的 "Id": "{Query.Id}" 属性所定义。

Azure Cosmos DB 输入绑定在函数配置文件 (function.json) 中提供的绑定列表中首先列出。

{ 
  "bindings": [ 
    { 
      "type": "cosmosDB", 
      "name": "ToDoItem", 
      "databaseName": "ToDoItems", 
      "collectionName": "Items", 
      "connectionStringSetting": "CosmosDBConnection", 
      "direction": "in", 
      "Id": "{Query.id}", 
      "PartitionKey": "{Query.partitionKeyValue}" 
    },
    { 
      "authLevel": "anonymous", 
      "name": "Request", 
      "type": "httpTrigger", 
      "direction": "in", 
      "methods": [ 
        "get", 
        "post" 
      ] 
    }, 
    { 
      "name": "Response", 
      "type": "http", 
      "direction": "out" 
    },
  ], 
  "disabled": false 
} 

run.ps1 文件包含 PowerShell 代码,该代码读取传入的文档并输出更改。

using namespace System.Net

param($Request, $ToDoItem, $TriggerMetadata)

Write-Host 'PowerShell HTTP trigger function processed a request'

if (-not $ToDoItem) { 
    Write-Host 'ToDo item not found'

    Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ 
        StatusCode = [HttpStatusCode]::NotFound 
        Body = $ToDoItem.Description 
    })

} else {

    Write-Host "Found ToDo item, Description=$($ToDoItem.Description)"

    Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ 
        StatusCode = [HttpStatusCode]::OK 
        Body = $ToDoItem.Description 
    }) 
}

HTTP 触发器,从路由数据查找 ID

下面的示例演示如何通过 Web API 读取和更新单个 Azure Cosmos DB 文档。 文档的唯一标识符通过 route 参数提供。 route 参数在 HTTP 请求绑定的 route 属性中定义,并在 Azure Cosmos DB "Id": "{Id}" 绑定属性中引用。

Azure Cosmos DB 输入绑定在函数配置文件 (function.json) 中提供的绑定列表中首先列出。

{ 
  "bindings": [ 
    { 
      "type": "cosmosDB", 
      "name": "ToDoItem", 
      "databaseName": "ToDoItems", 
      "collectionName": "Items", 
      "connectionStringSetting": "CosmosDBConnection", 
      "direction": "in", 
      "Id": "{id}", 
      "PartitionKey": "{partitionKeyValue}" 
    },
    { 
      "authLevel": "anonymous", 
      "name": "Request", 
      "type": "httpTrigger", 
      "direction": "in", 
      "methods": [ 
        "get", 
        "post" 
      ], 
      "route": "todoitems/{partitionKeyValue}/{id}" 
    }, 
    { 
      "name": "Response", 
      "type": "http", 
      "direction": "out" 
    }
  ], 
  "disabled": false 
} 

run.ps1 文件包含 PowerShell 代码,该代码读取传入的文档并输出更改。

using namespace System.Net

param($Request, $ToDoItem, $TriggerMetadata)

Write-Host 'PowerShell HTTP trigger function processed a request'

if (-not $ToDoItem) { 
    Write-Host 'ToDo item not found'

    Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ 
        StatusCode = [HttpStatusCode]::NotFound 
        Body = $ToDoItem.Description 
    })

} else { 
    Write-Host "Found ToDo item, Description=$($ToDoItem.Description)"

    Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{ 
        StatusCode = [HttpStatusCode]::OK 
        Body = $ToDoItem.Description 
    }) 
} 

队列触发器,使用 SqlQuery 获取多个文档

下面的示例演示如何读取多个 Azure Cosmos DB 文档。 函数的配置文件 (function.json) 定义了包含 sqlQuery 的绑定属性。 提供给 sqlQuery 属性的 SQL 语句选择提供给函数的文档集。

{ 
  "name": "Documents", 
  "type": "cosmosDB", 
  "direction": "in", 
  "databaseName": "MyDb", 
  "collectionName": "MyCollection", 
  "sqlQuery": "SELECT * from c where c.departmentId = {departmentId}", 
  "connectionStringSetting": "CosmosDBConnection" 
} 

run1.ps1 文件包含 PowerShell 代码,该代码读取传入的文档。

param($QueueItem, $Documents, $TriggerMetadata)

foreach ($Document in $Documents) { 
    # operate on each document 
} 

此部分包含的以下示例可以通过指定各种源提供的 ID 值来读取单个文档:

示例取决于使用的是 v1 还是 v2 Python 编程模型

队列触发器,从 JSON 查找 ID

以下示例演示了 Azure Cosmos DB 输入绑定。 该函数读取单个文档,并更新文档的文本值。

import logging
import azure.functions as func

app = func.FunctionApp()

@app.queue_trigger(arg_name="msg", 
                   queue_name="outqueue", 
                   connection="AzureWebJobsStorage")
@app.cosmos_db_input(arg_name="documents", 
                     database_name="MyDatabase",
                     collection_name="MyCollection",
                     id="{msg.payload_property}",
                     partition_key="{msg.payload_property}",
                     connection_string_setting="MyAccount_COSMOSDB")
@app.cosmos_db_output(arg_name="outputDocument", 
                      database_name="MyDatabase",
                      collection_name="MyCollection",
                      connection_string_setting="MyAccount_COSMOSDB")
def test_function(msg: func.QueueMessage,
                  inputDocument: func.DocumentList, 
                  outputDocument: func.Out[func.Document]):
     document = documents[id]
     document["text"] = "This was updated!"
     doc = inputDocument[0]
     doc["text"] = "This was updated!"
     outputDocument.set(doc)
     print(f"Updated document.")

HTTP 触发器,从查询字符串查找 ID

以下示例显示了一个检索单个文档的函数。 此函数由 HTTP 请求触发,该请求使用的查询字符串用于指定要查找的 ID 和分区键值。 该 ID 和分区键值用于从指定的数据库和集合中检索 ToDoItem 文档。

目前没有 v2 的等效样本。

HTTP 触发器,从路由数据查找 ID

以下示例显示了一个检索单个文档的函数。 此函数由 HTTP 请求触发,该请求使用的路由数据用于指定要查找的 ID 和分区键值。 该 ID 和分区键值用于从指定的数据库和集合中检索 ToDoItem 文档。

目前没有 v2 的等效样本。

队列触发器,使用 SqlQuery 获取多个文档

以下示例显示了使用绑定的 Azure Cosmos DB 输入绑定 Python 函数。 该函数使用队列触发器自定义查询参数检索 SQL 查询指定的多个文档。

队列触发器提供参数 departmentId{ "departmentId" : "Finance" } 的队列消息将返回财务部的所有记录。

目前没有 v2 的等效样本。

特性

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

Attribute 属性 说明
Connection 应用设置或设置集合的名称,用于指定如何连接到所查询的 Azure Cosmos DB 帐户。 有关详细信息,请参阅连接
DatabaseName 带有受监视的容器的 Azure Cosmos DB 数据库的名称。
ContainerName 要监视的容器的名称。
PartitionKey 指定用于查找分区键值。 可以包含绑定参数。 它是在分区的容器中进行查询所需的。
Id 要检索的文档的 ID。 此属性支持绑定表达式。 不要同时设置 IdSqlQuery 属性。 如果上述两个属性都未设置,则会检索整个容器。
SqlQuery 用于检索多个文档的 Azure Cosmos DB SQL 查询。 该属性支持运行时绑定,如以下示例中所示:SELECT * FROM c where c.departmentId = {departmentId}。 不要同时设置 IdSqlQuery 属性。 如果上述两个属性都未设置,则会检索整个容器。
PreferredLocations (可选)为 Azure Cosmos DB 服务中的异地复制数据库帐户定义首选位置(区域)。 值应以逗号分隔。 例如,China North,China North,China North

修饰符

仅适用于 Python v2 编程模型。

Python v2 函数可使用 cosmos_db_input 修饰器定义,该修饰器支持以下属性,具体取决于扩展版本:

properties 说明
arg_name 函数代码中使用的变量名称,表示发生更改的文档列表。
database_name 带有受监视的集合的 Azure Cosmos DB 数据库的名称。
container_name 受到监视的 Azure Cosmos DB 集合的名称。
connection 受到监视的 Azure Cosmos DB 的连接字符串。
partition_key 正在监视的 Azure Cosmos DB 的分区键。
id 要检索的文档的 ID。

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

批注

Java 函数运行时库中,对从 Azure Cosmos DB 读取数据的参数使用 @CosmosDBInput 注释。 此注释支持以下属性:

配置

仅适用于 Python v1 编程模型

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

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

function.json 属性 说明
type 必须设置为 cosmosDB
direction 必须设置为 in
name 函数代码中使用的变量名称,表示发生更改的文档列表。
连接 应用设置或设置容器的名称,用于指定如何连接到受监视的 Azure Cosmos DB 帐户。 有关详细信息,请参阅连接
databaseName 带有受监视的容器的 Azure Cosmos DB 数据库的名称。
containerName 要监视的容器的名称。
partitionKey 指定用于查找分区键值。 可以包含绑定参数。 它是在分区的容器中进行查询所需的。
id 要检索的文档的 ID。 此属性支持绑定表达式。 不要同时设置 idsqlQuery 属性。 如果上述两个属性都未设置,则会检索整个容器。
sqlQuery 用于检索多个文档的 Azure Cosmos DB SQL 查询。 该属性支持运行时绑定,如以下示例中所示:SELECT * FROM c where c.departmentId = {departmentId}。 不要同时设置 idsqlQuery 属性。 如果上述两个属性都未设置,则会检索整个容器。
preferredLocations (可选)为 Azure Cosmos DB 服务中的异地复制数据库帐户定义首选位置(区域)。 值应以逗号分隔。 例如,China East,China North,China North 2

有关完整示例的信息,请参阅示例部分

使用情况

函数成功退出时,对输入文档所做的任何更改都会自动保存。

Cosmos DB 输入绑定支持的参数类型取决于所用的 Functions 运行时版本、扩展包版本以及 C# 模态。

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

类型 说明
JSON 可序列化类型 Functions 会尝试将文档的 JSON 数据反序列化为普通的旧 CLR 对象 (POCO) 类型。

如果你希望函数处理查询中的多个文档,可将 Cosmos DB 输入绑定绑到以下类型:

类型 说明
IEnumerable<T>,其中 T 是 JSON 序列化的类型 查询返回的实体的枚举。 每个条目表示一个事件。
CosmosClient (预览版1
连接到 Cosmos DB 帐户的客户端。
Database (预览版1
连接到 Cosmos DB 数据库的客户端。
容器 (预览版1
连接到 Cosmos DB 容器的客户端。

1 若要使用这些类型,需要引用 Microsoft.Azure.Functions.Worker.Extensions.CosmosDB 4.3.1-preview1 或更高版本以及 SDK 类型绑定的常见依赖项

Java 函数运行时库中,@CosmosDBInput 注释向函数公开 Azure Cosmos DB 数据。 可以将此注释与本机 Java 类型、POJO 或使用了 Optional<T> 的可为 null 的值一起使用。

使用 context.extraInputs.get() 访问文档。

函数退出时不会自动对文档进行更新。 若要在函数中更新文档,请使用输出绑定。 有关更多详细信息,请参阅 PowerShell 示例

数据通过 DocumentList 参数提供给函数。 不会自动保留对文档所做的更改。

连接

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

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

连接字符串

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

基于标识的连接

如果使用 4.x 或更高版本的扩展,则无需将连接字符串与机密一起使用,可以使应用使用 Azure Active Directory 标识。 为此,需要定义公共前缀下的设置,该前缀映射到触发器和绑定配置中的 connection 属性。

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

属性 环境变量模板 说明 示例值
帐户终结点 <CONNECTION_NAME_PREFIX>__accountEndpoint Azure Cosmos DB 帐户终结点 URI。 https://<database_account_name>.documents.azure.cn: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 将容器创建视为管理操作。 它不可用作触发器的数据平面操作。 在设置函数之前,需确保创建触发器所需的容器(包括租用容器)。

后续步骤