Cosmos DB-最终文件的计算

时间:2020-06-19 09:25:03

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

寻找在插入过程中在Cosmos DB中计算完整文档的最佳方法。

我有两种类型的文档: 我有多个数据文件实例。

{
    "name":"John",
    "age":31,
    "city":"New York",
    "Value": ""
}

设置文档

{
    "name":"John",
    "multiplier":2
}

我希望容器中有最终文档,以便使用2个文档中excel中的公式。在这种情况下,乘数x age =值:

{
    "name":"John",
    "age":31,
    "city":"New York"
    "value":62
}

我当时想拥有一个Data容器和Settings容器,以及一个Data容器中的触发器,该触发器在插入期间将使用预触发来访问设置容器,并且在该触发器中具有一个计算逻辑来在Data容器中创建最终文档。它看到cosmos db触发器是有限的,并且我无法从触发器访问其他容器文档。

  • 如果我将这两个文档放在同一容器中,可以使用触发器进行这种计算吗?
  • 如果我不能使用触发器,那么此方案和Azure函数的最佳用途是什么?
  • 还有其他最佳做法建议吗?在SQL Server中,我只使用计算列或触发器。

1 个答案:

答案 0 :(得分:0)

第一个问题:

如果我将这两个文档放在同一容器中,可以使用触发器进行这种计算吗?

是的,您可以执行此计算。但是您的两种类型的文档必须位于同一逻辑分区中。其原因请参考Transactions

第三个问题:

还有其他最佳做法建议吗?在SQL Server中,我只使用计算列或触发器。

如果您熟悉Azure函数,则可以使用它来进行计算。 在cosmos DB中,如果要调用触发器,则必须这样设置requestOption

ItemRequestOptions request = new ItemRequestOptions
{
    PreTriggers = new List<string> { "insertValue" }
};
ItemResponse<Users> userResponse = await this.container.CreateItemAsync<Users>(user, null, request);

如果使用Azure Function,则无需设置requestOption

下面是我的测试触发代码(我已经插入了设置文件):

function insertValue(){

    var context = getContext();
    var container = context.getCollection();

    var request = context.getRequest();
    var multiplier;
    // item to be created in the current operation
    var itemToCreate = request.getBody();
    var name = itemToCreate.name;

    var filterQuery = 'SELECT * FROM users u WHERE u.name = "' + name +'" and u.multiplier != null';
    var accept = container.queryDocuments(container.getSelfLink(), filterQuery,
    updateMetadataCallback);
    if(!accept) throw "Unable to find document, abort";

    
    function updateMetadataCallback(err, items, responseOptions) {
        if(err) throw new Error("Error" + err.message);
            if(items.length != 1) throw 'Unable to find  document';

            var userItem = items[0];
            multiplier = userItem.multiplier;
            // update metadata
            if(multiplier){
                itemToCreate["Value"] = multiplier * itemToCreate["age"];
                request.setBody(itemToCreate);
            }
            
    }
}

希望这可以为您提供帮助。