Избегайте UpsertAsyn c в CosmosDB - запустите команду update SQL - PullRequest
0 голосов
/ 19 апреля 2020

У меня есть структура ниже в коллекции Cosmos (где эта структура не будет изменена)

{
    "attribute1": "",
    "attribute2": "",
    "attribute3": "11181",
    "attribute4": "Text value",
    "companies": [
        {
            "companyId": "Guid",
            "companyName": "Value"
        }
    ],
    "id": "ec4c18d9-178d-43d4-a2b0-093b160bfd06"
}

У меня есть процесс, который изменяет список компаний

Есть ли способ запустить оператор «ОБНОВЛЕНИЕ» в Cosmos для обновления только списка компаний?

Текущая реализация, показанная ниже, занимает 1 минуту, что намного дольше, чем мне хотелось бы

public void RandomizeCompanies()
{
  foreach (var item in _items)
  {
      //Clear companies list and add random elements to the list
  }
}

public async Task ChangeCompaniesAsync()
{
    await ConnectToDatabaseAsync();
    await GetItemsFromCosmosAsync().ConfigureAwait(false);
    RandomizeCompanies();

    try
    {
        Console.WriteLine($"Starting...");
        var stopwatch = Stopwatch.StartNew();
        var tasks = new List<Task>(_items.Count);

        foreach (var item in _items)
        {
            tasks.Add(_cosmosConnection.Container.UpsertItemAsync(item, new PartitionKey(item.Id)));
        }
        await Task.WhenAll(tasks);
        stopwatch.Stop();

        Console.WriteLine($"Finished writing {_items.Count} items in {stopwatch.Elapsed}.");
    }
    catch (Exception ex)
    {
         Console.WriteLine(ex);
    }
    finally
    {
        Console.WriteLine("Cleaning up resources...");
    }
  }
}

Что-то вроде

var tasks = new List<Task>(_items.Count);
foreach (var item in _items)
{
    tasks.Add( Run update statement that updates companies list to be items.Companies  );
}
await Task.WhenAll(tasks);

Текущая реализация не идеальна, потому что я сериализую весь документ, хотя изменяется только небольшая часть

Пол

Ответы [ 2 ]

2 голосов
/ 19 апреля 2020

Как отмечено в другом ответе, частичные обновления в настоящее время не поддерживаются. Однако, даже если он поддерживается, вполне возможно, что это будет не так эффективно, как если бы вы разработали свою модель для отделения stati c от часто меняющихся данных. Это особенно актуально для документов большого размера с глубоко вложенной структурой. Эти предложения по моделированию, приведенные ниже, включают использование свойства «type» для различения guish типа сущности и с общими «ключом раздела» и «id», чтобы их можно было запрашивать вместе. Необходимо рассмотреть два основных сценария ios.

Сценарий 1 (stati c свойства и свойства с частыми обновлениями): в этом сценарии у вас есть большой набор свойств stati c и меньшее число часто обновляемых свойств. В этом сценарии модели stati c свойства в качестве одного документа и часто обновляемые свойства в качестве второго (меньшего) документа с тем же ключом разделения и идентификатором. Если он не меньше, отделяйте его чаще от менее часто обновляемых свойств.

Сценарий 2 (stati c свойства и свойства в неограниченном массиве): в этом сценарии ios у вас есть такой же большой набор данных. c свойств, но постоянно растущий список свойств в массиве. Это не обязательно должно быть конкретно неограниченным, но когда у вас есть массив, который обычно продолжает расти, более эффективно сделать каждый элемент в этом массиве отдельным документом с общим ключом раздела и идентификатором и просто вставить в контейнер.

Для получения дополнительной информации о некоторых из этих концепций см. Моделирование данных в Azure Cosmos DB

Надеюсь, что это полезно.

1 голос
/ 19 апреля 2020

@ Пол Частичные обновления документов невозможны в Cosmos SQL API. Это запрос функции на голос пользователя. https://feedback.azure.com/forums/263030-azure-cosmos-db/suggestions/6693091-be-able-to-do-partial-updates-on-document

...