你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
适用于 Azure Functions 2.x 及更高版本的 Azure Cosmos DB 输入绑定
Azure Cosmos DB 输入绑定会使用 SQL API 检索一个或多个 Azure Cosmos DB 文档,并将其传递给函数的输入参数。 可根据调用函数的触发器确定文档 ID 或查询参数。
有关设置和配置详细信息,请参阅概述。
注意
当集合已分区时,查找操作还必须指定分区键值。
重要
本文使用选项卡来支持多个版本的 Node.js 编程模型。 v4 模型已正式发布,旨在为 JavaScript 和 TypeScript 开发人员提供更为灵活和直观的体验。 有关 v4 模型工作原理的更多详细信息,请参阅 Azure Functions Node.js 开发人员指南。 要详细了解 v3 和 v4 之间的差异,请参阅迁移指南。
Azure Functions 支持两种 Python 编程模型。 定义绑定的方式取决于选择的编程模型。
使用 Python v2 编程模型,可以直接在 Python 函数代码中使用修饰器定义绑定。 有关详细信息,请参阅 Python 开发人员指南。
本文同时支持两个编程模型。
示例
除非另有说明,否则本文中的示例针对的都是 Azure Cosmos DB 扩展的版本 3.x。 若要与扩展版本 4.x 一起使用,需要将 collection
属性和属性名称中的字符串替换为 container
。
可使用以下 C# 模式之一来创建 C# 函数:
- 独立辅助角色模型:编译的 C# 函数,该函数在独立于运行时的工作进程中运行。 需要独立工作进程才能支持在 LTS 和非 LTS 版 .NET 和 .NET Framework 上运行的 C# 函数。 独立工作进程函数的扩展使用
Microsoft.Azure.Functions.Worker.Extensions.*
命名空间。 - 进程内模型:编译的 C# 函数,该函数在与 Functions 运行时相同的进程中运行。 在此模型的变体中,可以使用 C# 脚本运行 Functions,该脚本主要用于 C# 门户编辑。 进程内函数的扩展使用
Microsoft.Azure.WebJobs.Extensions.*
命名空间。
重要
对进程内模型的支持将于 2026 年 11 月 10 日结束。 为获得完全支持,强烈建议将应用迁移到独立工作模型。
本部分包含需要 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}");
}
}
本部分包含以下示例:
- HTTP 触发器,从查询字符串查找 ID - 字符串参数
- HTTP 触发器,从查询字符串查找 ID - POJO 参数
- HTTP 触发器,从路由数据查找 ID
- HTTP 触发器,使用 SqlQuery 从路由数据查找 ID
- HTTP 触发器,使用 SqlQuery 从路由数据获取多个文档(C# 脚本)
这些示例引用简单的 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[]
,因为可能会返回许多文档,具体取决于查询条件。
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
文档。
HTTP 触发器,从路由数据查找 ID
以下示例显示了一个检索单个文档的函数。 此函数由 HTTP 请求触发,该请求使用的路由数据用于指定要查找的 ID 和分区键值。 该 ID 和分区键值用于从指定的数据库和集合中检索 ToDoItem
文档。
队列触发器,使用 SqlQuery 获取多个文档
以下示例显示了使用绑定的 Azure Cosmos DB 输入绑定 Python 函数。 该函数使用队列触发器自定义查询参数检索 SQL 查询指定的多个文档。
队列触发器提供参数 departmentId
。 { "departmentId" : "Finance" }
的队列消息将返回财务部的所有记录。
特性
进程内和独立工作进程 C# 库使用特性来定义函数。 C# 脚本改用 function.json 配置文件,如 C# 脚本指南中所述。
Attribute 属性 | 说明 |
---|---|
Connection | 应用设置或设置集合的名称,用于指定如何连接到所查询的 Azure Cosmos DB 帐户。 有关详细信息,请参阅连接。 |
DatabaseName | 带有受监视的容器的 Azure Cosmos DB 数据库的名称。 |
ContainerName | 要监视的容器的名称。 |
PartitionKey | 指定用于查找分区键值。 可以包含绑定参数。 它是在分区的容器中进行查询所需的。 |
Id | 要检索的文档的 ID。 此属性支持绑定表达式。 不要同时设置 Id 和 SqlQuery 属性。 如果上述两个属性都未设置,则会检索整个容器。 |
SqlQuery | 用于检索多个文档的 Azure Cosmos DB SQL 查询。 该属性支持运行时绑定,如以下示例中所示:SELECT * FROM c where c.departmentId = {departmentId} 。 不要同时设置 Id 和 SqlQuery 属性。 如果上述两个属性都未设置,则会检索整个容器。 |
PreferredLocations | (可选)为 Azure Cosmos DB 服务中的异地复制数据库帐户定义首选位置(区域)。 值应以逗号分隔。 例如,East US,South Central US,North Europe 。 |
修饰符
仅适用于 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 编程模型。
下表解释了在 function.json 文件中设置的绑定配置属性,其中属性因扩展版本而异。
function.json 属性 | 说明 |
---|---|
type | 必须设置为 cosmosDB 。 |
direction | 必须设置为 in 。 |
name | 函数代码中使用的变量名称,表示发生更改的文档列表。 |
连接 | 应用设置或设置容器的名称,用于指定如何连接到受监视的 Azure Cosmos DB 帐户。 有关详细信息,请参阅连接。 |
databaseName | 带有受监视的容器的 Azure Cosmos DB 数据库的名称。 |
containerName | 要监视的容器的名称。 |
partitionKey | 指定用于查找分区键值。 可以包含绑定参数。 它是在分区的容器中进行查询所需的。 |
id | 要检索的文档的 ID。 此属性支持绑定表达式。 不要同时设置 id 和 sqlQuery 属性。 如果上述两个属性都未设置,则会检索整个容器。 |
sqlQuery | 用于检索多个文档的 Azure Cosmos DB SQL 查询。 该属性支持运行时绑定,如以下示例中所示:SELECT * FROM c where c.departmentId = {departmentId} 。 不要同时设置 id 和 sqlQuery 属性。 如果上述两个属性都未设置,则会检索整个容器。 |
preferredLocations | (可选)为 Azure Cosmos DB 服务中的异地复制数据库帐户定义首选位置(区域)。 值应以逗号分隔。 例如 East US,South Central US,North Europe 。 |
有关完整示例的信息,请参阅示例部分。
使用情况
函数成功退出时,对输入文档所做的任何更改都会自动保存。
Cosmos DB 输入绑定支持的参数类型取决于所用的 Functions 运行时版本、扩展包版本以及 C# 模态。
如果你希望函数处理单个文档,可将 Cosmos DB 输入绑定绑到以下类型:
类型 | 说明 |
---|---|
JSON 可序列化类型 | Functions 会尝试将文档的 JSON 数据反序列化为普通的旧 CLR 对象 (POCO) 类型。 |
如果你希望函数处理查询中的多个文档,可将 Cosmos DB 输入绑定绑到以下类型:
类型 | 说明 |
---|---|
IEnumerable<T> ,其中 T 是 JSON 序列化的类型 |
查询返回的实体的枚举。 每个条目表示一个事件。 |
CosmosClient1 | 连接到 Cosmos DB 帐户的客户端。 |
数据库1 | 连接到 Cosmos DB 数据库的客户端。 |
容器1 | 连接到 Cosmos DB 容器的客户端。 |
1 若要使用这些类型,需要引用 Microsoft.Azure.Functions.Worker.Extensions.CosmosDB 4.4.0 或更高版本以及 SDK 类型绑定的常见依赖项。
在 Java 函数运行时库中,@CosmosDBInput 注释向函数公开 Azure Cosmos DB 数据。 可以将此注释与本机 Java 类型、POJO 或使用了 Optional<T>
的可为 null 的值一起使用。
函数退出时不会自动对文档进行更新。 若要在函数中更新文档,请使用输出绑定。 有关更多详细信息,请参阅 PowerShell 示例。
数据通过 DocumentList
参数提供给函数。 不会自动保留对文档所做的更改。
连接
connectionStringSetting
/connection
和 leaseConnectionStringSetting
/leaseConnection
属性是对指定应用应该如何连接到 Azure Cosmos DB 的环境配置的引用。 这些属性可以指定:
- 包含连接字符串的应用程序设置的名称
- 多个应用程序设置的共享前缀的名称,共同定义基于标识的连接。 此选项仅适用于 4.x 或更高版本的扩展中的
connection
和leaseConnection
版本。
如果配置的值既是单个设置的完全匹配,也是其他设置的前缀匹配,则使用完全匹配。
连接字符串
数据库帐户的连接字符串应存储在应用程序设置中,其名称与绑定配置的 connection 属性指定的值匹配。
基于标识的连接
如果使用版本 4.x 或更高版本的扩展,而不是结合使用连接字符串与机密,则可以要求应用使用 Microsoft Entra 标识。 为此,需要定义公共前缀下的设置,该前缀映射到触发器和绑定配置中的 connection 属性。
在此模式下,扩展需要以下属性:
属性 | 环境变量模板 | 说明 | 示例值 |
---|---|---|---|
帐户终结点 | <CONNECTION_NAME_PREFIX>__accountEndpoint |
Azure Cosmos DB 帐户终结点 URI。 | https://<database_account_name>.documents.azure.com:443/ |
可以设置其他属性来自定义连接。 请参阅基于标识的连接的通用属性。
在 Azure Functions 服务中托管时,基于标识的连接将使用托管标识。 默认情况下使用系统分配的标识,但可以使用 credential
和 clientID
属性来指定用户分配的标识。 请注意,不支持为用户分配的标识配置资源 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 将容器创建视为管理操作。 它不可用作触发器的数据平面操作。 在设置函数之前,需确保创建触发器所需的容器(包括租用容器)。