Cosmos DB - расчет итогового документа - PullRequest
0 голосов
/ 19 июня 2020

Ищете лучший способ вычислить полный документ в Cosmos DB во время вставки.

У меня есть два типа документов: Документы данных, у меня есть несколько их экземпляров.

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

Настройка документа (ов)

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

Я хочу, чтобы в моем контейнере был окончательный документ, чтобы использовать формулу, как в Excel из 2 документов. В этом случае multiplier x age = value:

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

Я думал иметь контейнер данных и контейнер настроек и триггер в контейнере данных, который во время вставки будет использовать предварительный триггер для доступа к контейнеру настроек и в этом У триггера есть лог для расчета c для создания окончательного документа в контейнере данных. Он видит, что триггер cosmos db ограничен, и я не могу получить доступ к другому документу контейнера из триггера.

  • Если бы я поместил эти два документа в один контейнер, могу ли я использовать триггер для таких вычислений?
  • Если я не могу использовать триггер, что лучше всего использовать для этого сценария и функции Azure?
  • Какие-либо другие рекомендации по передовой практике? На сервере SQL я бы просто использовал вычисляемый столбец или триггер.

1 Ответ

0 голосов
/ 22 июня 2020

Первый вопрос:

Если бы я поместил эти два документа в один контейнер, могу ли я использовать триггер для такого расчета?

Да, вы можете это сделать Но ваш двухтипный документ должен находиться в одном логическом разделе. Причину этого см. в Транзакции .

Третий вопрос:

Любой другой рекомендации передовой практики? На сервере SQL я бы просто использовал вычисляемый столбец или триггер.

Если вы знакомы с функциями 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, вам не нужно устанавливать 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);
            }
            
    }
}

Надеюсь, это поможет вам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...