【问题标题】:How to update a doc in a collection with Azure function Cosmos DB trigger?如何使用 Azure 函数 Cosmos DB 触发器更新集合中的文档?
【发布时间】:2019-12-13 19:20:54
【问题描述】:

当他们在 CosmosDB 上创建时,我需要使用来自其他文档 (type2) 的数据更新一些文档 (type1)。我决定使用 javascript Azure Functions 和 cosmosDBTrigger,无服务器 Azure 选项。我在绑定表达式以配置 functions.json 以获取与触发函数的 doc-type2 关联的 doc-type1 时遇到问题。任何帮助都会很棒。

CosmosDB 文档类型 1:

{
    "type": "type1"
    "id": "123",
    "serial" : "123",
    "lastconf": []
}

CosmosDB 文档类型 2:

{
    "type": "type2"
    "id": "qwe",
    "idtype1" : "123",
    "conf1":1
}

函数.json

{
    "bindings": [{
        "name": "documents",
        "type": "cosmosDBTrigger",
        "direction": "in",
        "leaseCollectionName": "leases",
        "connectionStringSetting": "_DOCUMENTDB",
        "databaseName": "db",
        "collectionName": "dbDev",
        "createLeaseCollectionIfNotExists": true
    },
    {
      "name": "inputDocumentIn",
      "type": "cosmosDB",
      "databaseName": "db",
      "collectionName": "dbDev",
      "id": "{idtype1}", // sqlQuery ??
      "connectionStringSetting": "_DOCUMENTDB",
      "direction": "in"
  },
  {
      "name": "inputDocumentOut",
      "type": "cosmosDB",
      "databaseName": "db",
      "collectionName": "dbDev",
      "createIfNotExists": false,
      "connectionStringSetting": "_DOCUMENTDB",
      "direction": "out"
  } ]
}

index.js:

module.exports = async function(context, documents, inputDocumentIn, inputDocumentOut) {
   context.log('JavaScript trigger function processed a request.');

   if (!!documents && documents.length > 0) {

       context.log('Documents: ', documents);

       inputDocumentOut = inputDocumentIn;
       inputDocumentOut.lastconf = documents.conf1; //documents[i].conf1; ??

       context.log('inputDocumentOut: ', inputDocumentOut); 
   }
}

【问题讨论】:

    标签: azure azure-functions azure-cosmosdb azure-triggers


    【解决方案1】:

    Cosmos DB 触发器将文档列表作为有效负载发送。由于内容是一个列表,而不是单个对象/文档,因此使用输入绑定将不起作用(您的 inputDocumentIn 绑定)。

    通过检查您的绑定配置,我注意到的另一件事是,您的输出绑定正在写入触发器正在侦听的同一个容器/帐户,您实际上是在创建一个循环(您编写的文档将再次触发函数) .

    如果您想触发函数、接收更改 (documents) 并生成输出,您通常会遍历结果,并将结果输出到不同的容器中。如果确实需要将输出发送到同一个集合,则需要添加一些逻辑来过滤来自 documents 列表的那些。

    如果您需要执行查询,执行可能还需要作为循环的一部分进行,但是没有可以帮助您的绑定,您需要有一个 Client 并手动执行这些操作。

    在输出绑定中保存文档,我猜这也需要在循环中发生(因为您希望在每个函数执行中保存多个)当然可以使用数组:

    module.exports = async function(context, documents, inputDocumentIn, inputDocumentOut) {
       context.log('JavaScript trigger function processed a request.');
    
       if (!!documents && documents.length > 0) {
    
           context.log('Documents: ', documents);
           var documentsToSave = [];
    
           for(var i = 0; i < documents.length; i++)
           {
                var document = documents[i];
                var documentToSave = {};
                // process document, maybe assign property values to documentToSave from document
                documentsToSave.push(documentToSave);
           }
    
           inputDocumentOut = documentsToSave;
       }
    }
    

    【讨论】:

    • 我不明白为什么 CosmosDB 触发器会发送文档列表,而不是在创建/更新 CosmosDB 上的唯一文档时抛出触发器?
    • 文档在这里docs.microsoft.com/azure/cosmos-db/change-feed-functions。与事件中心触发器一样,在一个函数执行和下一个函数执行之间,可能会发生多个操作(创建和更新),因此不是每次操作获取一个触发器(这在消费计划中会非常昂贵),而是执行包含列表文件。
    猜你喜欢
    • 2019-01-04
    • 2018-06-02
    • 1970-01-01
    • 1970-01-01
    • 2023-04-04
    • 2023-01-31
    • 2020-05-14
    • 2022-06-23
    相关资源
    最近更新 更多