如何在Windows Azure存储上查询云Blob

29
我正在使用Microsoft.WindowsAzure.StorageClient来操作Azure存储中的blob。 我已经到达了用户需要列出上传文件并修改/删除它们的点。 由于一个容器中有许多文件,因此查询Azure存储服务以仅返回所需文件的最佳方法是什么?另外,我想能够仅返回特定数量的blob,以便我可以实现分页。
CloudBlobContainer中有一个名为ListBlobs的方法,但似乎它返回容器中的所有blob。这对我不起作用。
我在这个主题上进行了很多搜索,但没有找到任何有用的东西。 这个link只显示了基础知识。
--------- 编辑
我的下面的答案没有懒惰地检索blob,而是检索容器中的所有blob,然后过滤结果。 目前还没有解决方案可以懒惰地检索blob。
8个回答

34
方法ListBlobs是懒惰地检索容器中的块。因此,您可以针对该方法编写查询,这些查询直到你循环(或使用ToList或其他某些方法将对象实体化为列表)时才会执行。

通过几个例子,事情会变得更清晰。对于那些不知道如何获取Azure存储帐户中容器引用的人,我建议参考这个教程

按最后修改日期排序并获取第2页(每页10个Blob):

blobContainer.ListBlobs().OfType<CloudBlob>()
         .OrderByDescending(b=>b.Properties.LastModified).Skip(10).Take(10);

获取特定类型的文件。如果您在上传时设置了ContentType(我强烈建议您这样做),则此方法将有效:

blobContainer.ListBlobs().OfType<CloudBlob>()
         .Where(b=>b.Properties.ContentType.StartsWith("image"));

获取 .jpg 文件并按文件大小排序,假设您使用文件名及其扩展名命名:

blobContainer.ListBlobs().OfType<CloudBlob>()
    .Where(b=>b.Name.EndsWith(".jpg")).OrderByDescending(b=>b.Properties.Length);

最后,除非您告诉它执行查询,否则查询不会被执行:

var blobs = blobContainer.ListBlobs().OfType<CloudBlob>()
                          .Where(b=>b.Properties.ContentType.StartsWith("image"));

foreach(var b in blobs) //This line will call the service, 
                        //execute the query against it and 
                        //return the desired files
{
   // do something with each file. Variable b is of type CloudBlob
}

我已经测试了你的代码Gorgi(第一个示例),当我使用.Skip(1).Take(1)时,它仍然检索到多个项,因此似乎没有进行延迟加载。 - GeertvdC
@GeertvdC 我刚试了一下,结果如预期。你能把你尝试过的内容粘贴一下吗? - Gorgi Rankovski
3
天啊,你说得对。在ListBlobs()的文档中写着它会惰性地检索blobs,但是看起来你不能在属性上编写查询语句 :\唯一可以查询的是blobs名称前缀 - 例如ListBlobs("test") - 这只返回一个文件。 - Gorgi Rankovski
5
你好 Gorgi, blobContainer.ListBlobs() 方法返回的是一个 IEnumerable 而非 IQueryable,在 .NET 中按照惯例,IEnumerable 用于先将所有数据从服务器加载到内存中,然后再查询它们,与之相反的是 IQueryable 解析查询并将仅返回合法结果,而且都是以延迟加载的方式实现的。 http://www.codeproject.com/Tips/468215/Difference-Between-IEnumerable-and-IQueryable - James Roeiter
仅仅因为容器懒惰地检索 Blob 并不意味着它正在使用任何基于编译的 LINQ 查询的高级搜索。很可能,它只是从一个 Blob 移动到另一个 Blob,在检索每个 Blob 后运行您的查询。 - NathanAldenSr
显示剩余5条评论

21

我对Windows Azure Blob Storage的认识是它很基础,非常地基础。你应该仅将文档和相关元数据存储在其中,并通过ID检索单个blob。

最近,我将一个应用程序从MongoDB迁移到了Windows Azure Blob Storage。从MongoDB来,我希望有一堆不同的有效方式来检索文档。迁移后,我现在依赖传统的关系型数据库和ElasticSearch将blob信息以更可搜索的方式存储。

Windows Azure Blob Storage如此受限,这真的太糟糕了。我希望在未来能看到大大增强的搜索功能(例如,按元数据、属性、blob名称正则表达式等进行搜索)。此外,基于map/reduce的索引将是很棒的。如果Microsoft做到这些,他们有机会从其他文档存储系统转换很多人。


感谢@NathanAldenSr。看起来这个问题很受欢迎,所以我把你的答案标记为正确答案。 - Gorgi Rankovski

4

编辑

现在预览版推出了Azure存储的Blob索引,这是一个可以添加到Blob(新的或现有的)的元数据的托管索引。这将消除使用创意容器名称进行伪索引或自行维护次要索引的需要。

原始答案

为了返回特定结果,一种可能的选择是使用Blob和/或容器前缀来有效地索引你正在存储的内容。例如,你可以在添加Blob时加上日期和时间作为前缀,或者根据你的用例,你可以加上用户作为前缀来“索引”你的Blob。然后,你可以在ListBlobs[Segmented]调用中使用此前缀或其一部分以返回特定的结果,显然,你需要先放置最通用的元素,然后放置更具体的元素,例如:

2016_03_15_10_15_blobname

这将允许您获取所有2016年的blob,或者是2016年3月的blob等等,但不能在不进行多次调用的情况下获取任何一年的三月blob。
这种方法的缺点是,如果您需要重新索引blob,则需要删除并使用新名称重新创建它们。
对于分页,通常可以使用ListBlobsSegmented方法,它将提供一个续订标记,您可以使用该标记实现分页。尽管如此,如果您需要跳过页面,它就无法满足您的需求,因为它仅起始于上一组实际结果结束的地方。其中一个选择是计算您需要跳过的页数,获取它们并丢弃它们,然后获取您想要的实际页面。如果每个容器中有大量的blobs,这可能会很快变得非常低效...
您还可以将其作为回退方法,并使用逐页方法存储续订标记,以便用户按顺序单击一页到下一页,或者您可以潜在地缓存blob名称并从中进行自己的分页。
您还可以将这两种方法结合起来,例如按照您的“索引”进行过滤,然后在结果上进行分页。

你知道关于按前缀查询的速度有什么信息吗?它是否被索引或者需要扫描整个容器? - Andy
@Andy已编辑答案并添加了一些有用的链接。 - Matt
所有这些文档都专门讨论表存储。你有没有找到关于块存储类似的内容?具体而言,如果我在容器中有一百万个块,并且我想通过前缀查询定位其中的十个,这是否需要进行完全扫描? - Andy
抱歉,在编辑之前我甚至没有重新阅读我的原始答案,我以为我们在谈论表存储!我所知道的关于 Blob 存储性能的唯一事情是:1)小心如何分区和设计容器/ blob 名称,或者2)支付高性能存储。第三个选项是单独在您选择的数据存储中索引容器或 blob 名称。 - Matt
@Andy - 请查看我的编辑,一个新的托管索引功能刚刚被宣布。 - Matt

1

0
Azure Data Lake Gen 2将支持使用USQL搜索存储在数据湖中的数据。Blob存储API可用于存储和检索该数据。

0

目前,U-SQL不支持交互式查询/搜索。

对于我的用例,我计划利用Azure Blob存储的低成本优势,并在每个新的Blob文件创建事件触发Azure函数,在Blob上进行数据转换,以将处理后的输出提供给支持查询的Azure Cosmos DB或RDBMS。


0
只需从资源中配置诊断设置以将文件保留在 Log Analytics 工作区中,您就可以开始了。 我知道这篇文章很旧,但看起来它仍然被索引用于类似的问题。

Log analytics


0

在此期间,Azure Blob Storage得到了增强,以支持索引标签。

引用:使用Blob索引标签管理和查找Azure Blob数据

随着数据集变得越来越大,在一堆数据中找到特定对象可能会变得困难。Blob索引标签通过使用键值索引标签属性提供数据管理和发现功能。您可以对单个容器或存储帐户中的所有容器中的对象进行分类和查找。随着数据需求的变化,可以通过更新其索引标签动态地对对象进行分类。对象可以保留其当前容器组织中的位置。

Blob索引标签可让您:

  • 使用键值索引标签动态分类您的Blob
  • 快速查找整个存储帐户中特定标记的Blob
  • 基于索引标签的评估指定Blob API的条件行为
  • 在高级控制中使用索引标签,例如Blob生命周期管理等特性

源代码示例如下:

使用 blob 索引标签来管理和查找 Azure Blob 存储中的数据


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接