【问题标题】:Cosmos DB - calculation of final documentCosmos DB - 最终文档的计算
【发布时间】:2020-06-19 09:25:03
【问题描述】:

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

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

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

设置文档

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

我想在我的容器中保存最终文档,以便在 2 个文档中使用类似于 excel 中的公式。在这种情况下,乘数 x 年龄 = 值:

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

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

  • 如果我将这两个文档放在同一个容器中,我可以使用触发器进行这样的计算吗?
  • 如果我不能使用触发器,那么这个场景和 Azure 功能的最佳用途是什么?
  • 还有其他最佳实践建议吗?在 SQL Server 中,我只会使用计算列或触发器。

【问题讨论】:

  • 如果您认为我的回答对您有帮助,您可以将其标记为已回答。非常感谢。

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


【解决方案1】:

第一个问题:

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

是的,你可以做这个计算。但是你的两个类型的文档必须在同一个逻辑分区。这个原因请参考Transactions

第三个问题:

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

如果您熟悉 Azure Functions,则可以使用它来进行计算。 在 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);
            }
            
    }
}

希望对你有帮助。

【讨论】:

    猜你喜欢
    • 2022-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多