带有“ take”的Azure Tables异步查询过滤器未提供前#n个实体

时间:2018-10-12 05:06:06

标签: c# azure azure-table-storage

我想要与TableQuery过滤器匹配的数千个实体中排名前100位的实体(最近的实体),并且我尝试了两种方法:

  1. 第一次尝试是在foreach循环中使用索引计数器,使其达到“ 100”时中断。这给了我一个奇怪的随机数据子集,其中大部分数据丢失了,而不是100个实体。更像是几百个而不是偶数。

  2. 第二次尝试粘贴在下面,实际上忽略了我的继续标记,并将.take设置为“ 100”。这给了我确切的数量,与Take整数匹配,但是缺少许多实体。

每次尝试都可以得出不同的结果,我想我知道为什么,但是我不知道如何解决它以得到我需要的东西。我意识到出于性能原因,在时间戳上设置查询过滤器不是很好(没有索引...对吗?)。所以我应该用日期/时间值填充另一个字段以进行过滤吗?

        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 :(得分:1)

您可以参考doc中的 Log Tail Pattern

  

通过使用按相反的日期和时间顺序排序的 RowKey 值,检索最近添加到分区中的 n 个实体。

     

上下文和问题

     

一个常见的要求是能够检索最近创建的实体,例如,雇员提交的十个最近的费用索赔。表查询支持 $ top 查询操作以返回集合中的前 n 个实体:没有等效的查询操作返回最后一个 n 集合中的实体。

     

解决方案

     

使用 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
  

问题和注意事项

     

在决定如何实现此模式时,请考虑以下几点:

     
      
  • 您必须在反向滴答值前加零开头,以确保   字符串值按预期排序。

  •   
  • 您必须了解分区级别的可伸缩性目标。注意不要创建热点分区。

  •