Azure Blob C# 客户端 - 使用多个过滤器服务器端

Azure Blobs C# client - using multiple filters server side

我正在尝试加载 blob 名称以在我的程序中进行过滤,然后在应用所有过滤器后我计划下载并处理每个 blob。 目前我们有大约 3 万个 blob 存储在容器中,如下所示: year/month/day/hour/file.csv(或 file.json 对于未处理的文件)

我的程序需要动态输入开始和结束日期(最长 30 天)以供下载。使用 Azure.Storage.Blobs.BlobContainerItem 和方法 GetBlobs 允许我使用单个字符串前缀进行服务器端过滤。

如果我的日期是 2020/06/01 和 2020/06/02,程序运行速度非常快,大约需要 2 秒来获取 blob 并对其应用其余过滤器。但是,如果我有 2020/05/30 和 2020/06/01,那么我无法输入月份前缀,因为它只需要 1 个字符串,所以我的前缀将只是 2020,这大约需要 15 秒才能完成。其余的过滤在本地完成,但最大的延迟是 GetBlobs() 函数。

有没有其他方法可以从 .NETCore 应用程序使用多个过滤器服务器端?

相关函数如下:

        BlobContainerClient container = new BlobContainerClient(resourceGroup.Blob, resourceGroup.BlobContainer);
        var blobs = container.GetBlobs(prefix : CreateBlobPrefix(start, end))
            .Select(item=> item.Name)
            .ToList();
        blobs = FilterBlobList(blobs, filter, start, end);

    private string CreateBlobPrefix(DateTime start, DateTime end)
    {
        string prefix = null;
        bool sameYear = start.Year == end.Year;
        bool sameMonth = start.Month == end.Month;
        bool sameDay = start.Day == end.Day;
        if (sameYear)
        {
            prefix = start.Year.ToString();
            if (sameMonth)
            {
                if(start.Month<10)
                    prefix += "/0" + start.Month.ToString();
                else
                    prefix += "/" + start.Month.ToString();
                if (sameDay) 
                    if(start.Day<10)
                        prefix += "/0" + start.Day.ToString();
                    else
                        prefix += "/" + start.Day.ToString();
            }
        }
        return prefix;

编辑:这是我最后的做法。因为使用更好的指定前缀发出多个请求会更快,所以我做了以下操作:

代码如下:

        foreach (var blobPrefix in CreateBlobPrefix(start, end))
        {
            var currentList = container.GetBlobs(prefix: blobPrefix)
                .Select(item => item.Name)
                .ToList();
            blobs = blobs.Concat(currentList).ToList();
        }

您可以过滤多次,找到日期之间的共同点:

首先使用开始月份和年份 2020/05 的字符串前缀进行过滤,然后在本地进行精确日期过滤。

然后您可以逐渐增加 day/month 过滤器,直到达到范围的末尾。

步进的粒度实际上取决于为给定的平均结果数调用 Azure 所花费的时间。 另一个优点是您可以 运行 这些子查询并行。

我用过这个代码:

    var prefixDateFilters = Enumerable.Range(0, 1 + endDateInclusive.Subtract(startDateInclusive).Days)
                                      .Select(offset => startDateInclusive.AddDays(offset))
                                      .Select(date => $"{date.ToString(BlobFileDateTimeFormat)}").ToList();

    prefixFilters.AsParallel()
                 .Select(filter => containerClient.GetBlobs(prefix: filter))