Azure Blob C#客户端-使用多个筛选器服务器端



我正在尝试加载blob名称以在程序中进行过滤,然后在应用了所有过滤器后,我计划下载并处理每个blob。目前,我们有大约3万个Blob存储在这样的容器中:年/月/日/小时/file.csv(或未处理文件的file.json(

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

如果我的日期是2020/06/01和2020/06/02,程序运行速度非常快,大约需要2秒才能得到斑点并将其余的过滤器应用到它。然而,如果我有2020/05/30和202/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;

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

  • 在所选时间窗口中创建不同日期的列表(来自用户输入任何窗口的UI应用程序(
  • 对于创建的每个前缀,我将请求发送到Azure以获取Blob
  • 将所有blob名称连接到1个列表中
  • 通过对每个blob名称使用blob客户端来处理列表

这是代码:

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的开始月份和年份使用字符串前缀进行筛选,然后在本地进行筛选以获取确切日期。

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

步进的粒度实际上取决于为给定的平均结果数调用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))

最新更新