Несогласованные запросы к разделенной коллекции CosmosDB - PullRequest
0 голосов
/ 10 декабря 2018

У меня есть разделенная коллекция БД Cosmos, которая определена как неограниченная с пропускной способностью 1000. Она имеет следующую структуру документа:

"Id": "b42129d2-5467-450c-9f7e-744f78dfe1e7", // Primary key
"ArrayOfObjects": [
 {
     // other properties omitted for brevity
     "SubId": "ed2a49fb-51d4-45b4-9690-df0721d6a32f"
 },
 {
     "SubId": "35c87833-9bea-4151-86da-4d9c482ae1fe"
 },
 "ParitionKey": "b42"

Ключ разделения - это первые 3 буквы первичного ключа, которыеэто GUID.Это дает мне 32768 возможных разделов с хорошим количеством элементов.Я использую CosmosDB .NetCore SDK .В настоящее время существует ~ 170 тысяч документов в ~ 6 тысячах разделов.

У меня есть функциональность, в которой мне нужно извлечь документ из коллекции через «SubId», где я не знаю первичный ключ, что означает, что я делаюне знаю ключ раздела.К сожалению, я не могу изменить эту функцию для работы с первичным ключом, поскольку ее зависимость - это устаревшая система, которую нельзя изменить.

Что происходит, я успешно создаю новый документ, а затем в какой-то момент мне нужно запроситьдокумент с использованием «SubId».Что делается в C # следующим образом:

public async Task<DocumentModel> GetBySubId(string subId)
{
    var collectionId = _cosmosClient.CollectionId;
    var query = $@"SELECT * FROM {collectionId} c
                   WHERE ARRAY_CONTAINS(c.ArrayOfObjects, {{'SubId': '{subId}'}}, true)";

    var feedOptions = new FeedOptions { EnableCrossPartitionQuery = true };

    var docQuery = _cosmosClient.Client.CreateDocumentQuery(
            _collectionUri,
            query,
            feedOptions)
            .AsDocumentQuery();

    var executedQuery = await docQuery.ExecuteNextAsync<DocumentModel>();

     if (executedQuery.Count == 0)
     {
           return null;
     }

     return executedQuery.FirstOrDefault();
}

Иногда он успешно запрашивает, иногда нет, и я возвращаю ноль, затем из моего контроллера я возвращаю 404.

Почему это такстранно, потому что, если я проверяю базу данных и выполняю этот запрос напрямую, документ там есть и на самом деле не отсутствует, но по какой-то причине, когда я запрашиваю из C # с помощью SDK, он не может найти документ.У меня есть другие функциональные возможности, которые запрашивают с использованием первичного ключа (что теперь означает, что у меня есть ключ раздела) и SubId, и это прекрасно работает.Только когда я выполняю запрос с использованием самого SubId (без ключа раздела), он не может найти документ.

Учитывая вышесказанное, я думаю, что он как-то связан с запросами без ключа раздела.Что-то, чего мне не хватает при запросе без ключа раздела?

На данный момент я пробовал установить согласованность базы данных с Возможного на Сильный.Кажется, это не имеет значения.

Ответы [ 2 ]

0 голосов
/ 12 декабря 2018

Я из инженерной команды CosmosDB.

Вероятно, вы упомянули поведение, потому что иногда запрос не может завершить выполнение за одно продолжение.Убедитесь, что запрос завершает выполнение, опустошив продолжения.Вы можете найти образец здесь: https://docs.microsoft.com/en-us/azure/cosmos-db/performance-tips#throughput.Выполнение запроса не считается завершенным до тех пор, пока для IDocumentQuery.HasMoreResults установлено значение false.

0 голосов
/ 10 декабря 2018

В данный момент я пробовал установить согласованность базы данных с Eventual на Strong.Кажется, это не имеет никакого значения.

Из этого документа согласованность на уровне Strong гарантирует возврат самой последней принятой версии элемента.Согласно вашему описанию, среда, которую вы тестируете, не является операциями чтения с высокой степенью параллелизма.Итак, я думаю, что это не имеет ничего общего с уровнем согласованности.

Иногда он успешно запрашивает, иногда нет, и я возвращаю ноль, затем из моего контроллера я возвращаю 404.

По моему опыту, эта проблема капризна из-за узких мест в пропускной способности.Ключ раздела должен быть предоставлен при запросе многораздельной коллекции.Однако вы не знаете ключ разделения, это невозможно сделать, пока вы не установите EnableCrossPartitionQuery = true, который уже существует в вашем примере кода.Тогда ваш запрос будет пересекать все разделы, пока не будет найден конкретный документ.Кроме того, оператор array_contains добавляет бремя запросов.

Запросы Cosmos DB ограничены настройками пропускной способности и не будут охватывать всю базу данных бесконечно. Пожалуйста, обратитесь к этому документу .

Поскольку сейчас вы не можете настроить политику разделов, я предлагаю вам увеличить параметры пропускной способности, чтобы проверить проблему.

...