从 Azure Function 访问 CosmosDB(无输入绑定)

Access CosmosDB from Azure Function (without input binding)

我在 CosmosDB 中有 2 个集合,StocksStockPrices

StockPrices 集合包含所有历史价格,并不断更新。

我想创建 Azure 函数来侦听 StockPrices 更新 (CosmosDBTrigger),然后对触发器传递的每个 Document 执行以下操作:

  1. Stocks 集合中查找具有匹配代码的股票
  2. 更新 Stocks 集合中的股票价格

我无法使用 CosmosDB 输入绑定来执行此操作,因为 CosmosDBTrigger 传递 List(绑定仅在触发器传递单个项目时有效)。

我看到这个工作的唯一方法是如果我 foreachCosmosDBTrigger 列表上,然后从我的函数体访问 CosmosDB 并执行上面的步骤 1 和 2。

问题:如何从我的函数中访问 CosmosDB?

最终采纳了@Noah Stahl 的建议。将此留在这里作为替代。


无法弄清楚如何直接执行此操作,因此想出了一个解决方法:

  1. 在具有 Queue 输出绑定的 StockPrices 集合上添加具有 CosmosDBTrigger 的函数
  2. foreach 来自触发器的 Documents,序列化并添加到 Queue
  3. Stocks 集合添加具有 QueueTriggerCosmosDB 输入绑定的函数(PartitionKeyId 设置为 StockTicker), CosmosDB Stocks 集合
  4. 的输出绑定
  5. 使用 QueueTrigger
  6. 中的值从 CosmosDB 输入绑定更新 Stock
  7. 将更新的 Stock 分配给 CosmosDB 输出绑定参数(更新数据库中的记录)

这就是说,我想听听更直接的方法,因为我的方法看起来像是 hack。

其中一种 CosmosDB 绑定形式是获取一个 DocumentClient instance,它提供了对容器的全方位操作。这样,您应该能够将更改提要触发器和项目操作组合到同一个函数中,例如:

[FunctionName("ProcessStockChanges")]
public async Task Run(
    [CosmosDBTrigger(/* Trigger params */)] IReadOnlyList<Document> changedItems,
    [CosmosDB(/* Client params */)] DocumentClient client,
    ILogger log)
{
    // Read changedItems, 
    // Create/read/update/delete with client
}

.NET Core 也可以使用 dependency injection 为您的函数实例提供完整的自定义 service/repository class 以连接到 Cosmos。这是我的首选方法,因为我可以使用最新版本的 Cosmos SDK 进行验证、控制序列化等。

您可能是有意这样做的,但只是提到考虑将您的数据合并到单个容器中,例如按记录类型 (Stock/StockPrice) 和标识符的组合进行分区。这简化了事情,并且相对于多个容器可以更 cost/resource 高效。