Фильтр асинхронных запросов таблиц Azure с 'take' не дает топ #n сущностей - PullRequest
0 голосов
/ 12 октября 2018

Мне нужны первые 100 сущностей (самые последние) из нескольких тысяч сущностей, соответствующих моему фильтру TableQuery, и я попытался сделать это двумя способами:

  1. Первой попыткой было использование индексасчетчик в цикле foreach, чтобы сломаться, когда он достигнет "100".Это дало мне странное случайное подмножество данных, большинство из которых отсутствовало, а не 100 сущностей;больше как несколько сотен, а не четное число.

  2. Вторая попытка вставлена ​​ниже и, по сути, игнорирует мой токен продолжения, а также устанавливает .take в «100».Это дает мне точное количество объектов, совпадающих с целым целым, однако многие объекты отсутствуют.

Каждая попытка дает разные результаты, и я думаю, что знаю почему, но я не знаю, какисправить это, чтобы вернуть то, что мне нужно.Я понимаю, что установка фильтра запроса на метку времени не очень хороша для производительности (она не индексируется ... верно?).Так я должен заполнить другое поле со значением даты / времени, чтобы отфильтровать?

        public async Task<List<ActivityModel>> GetActivitiesAsync(string DomainName, string NodeId, string ComputerName)
    {
        List<ActivityModel> activities = new List<ActivityModel>();
        CloudTable cloudTable = TableConnection("NodeEvents");
        string domainFilter = TableQuery.GenerateFilterCondition("DomainName", QueryComparisons.Equal, DomainName);
        string nodeIdFilter = TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, NodeId);
        string computerNameFilter = TableQuery.GenerateFilterCondition("ComputerName", QueryComparisons.Equal, ComputerName);
        string filter1 = TableQuery.CombineFilters(domainFilter, TableOperators.And, nodeIdFilter);
        string filter2 = TableQuery.CombineFilters(filter1, TableOperators.And, computerNameFilter);
        TableContinuationToken continuationToken = null;

        var result = await cloudTable.ExecuteQuerySegmentedAsync(new TableQuery<ActivityModel>().Where(filter2).Take(100), continuationToken);

        if (result.Results != null)
        {
            foreach (ActivityModel entity in result.Results)
            {
                activities.Add(entity);
            }
        }

        return activities;
    }

1 Ответ

0 голосов
/ 12 октября 2018

Вы можете сослаться на Шаблон хвоста журнала в документе .

Извлечь n сущностей, недавно добавленных вразделить с помощью значения RowKey , которое сортирует в обратном порядке по дате и времени.

Контекст и проблема

Распространенным требованием является возможностьизвлекать самые последние созданные объекты, например, десять самых последних заявлений о расходах, представленных сотрудником.Табличные запросы поддерживают операцию запроса $ top для возврата первых n сущностей из набора: не существует эквивалентной операции запроса для возврата последних n сущностей вset.

Решение

Сохранять объекты, используя RowKey , который естественным образом сортирует в обратном порядке даты / времени, используя самую последнюю запись:всегда первая в таблице.

Например, чтобы иметь возможность получить десять самых последних заявлений о расходах, представленных сотрудником, вы можете использовать обратное значение тика, полученное из текущей даты / времени.В следующем примере кода C # показан один из способов создания подходящего значения «перевернутых тиков» для RowKey , который сортирует от самых последних к самым старым:

string invertedTicks = string.Format("{0:D19}", DateTime.MaxValue.Ticks - DateTime.UtcNow.Ticks);

Вы можете вернуться к значению даты и времени, используя следующий код:

DateTime dt = new DateTime(DateTime.MaxValue.Ticks - Int64.Parse(invertedTicks));

Запрос к таблице выглядит следующим образом:

https://myaccount.table.core.windows.net/EmployeeExpense(PartitionKey='empid')?$top=10

Проблемы и соображения

При принятии решения о том, как реализовать этот шаблон, учитывайте следующие моменты:

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

  • Вы должны знать о целях масштабируемости на уровне раздела.Будьте осторожны, не создавайте горячие точки.

...