【问题标题】:Azure Searching Metadata in blobsAzure 在 blob 中搜索元数据
【发布时间】:2018-03-10 09:29:38
【问题描述】:

我正在尝试找到一种方法,仅将带有与特定数据匹配的元数据的 blob 存储中的项目带回。所有字段都有一个名为“FlightNo”的键。

我真正想要的是一种方法来查找包含与元数据匹配的所有文件(listBlobs),因此向上一层,然后遍历该组数据,并找到更多匹配项,因为每个文件都有 5 项元数据。

这是我迄今为止非常不友好的代码。

 foreach (IListBlobItem item in container.ListBlobs(null, false))
        {
            if (item.GetType() == typeof(CloudBlockBlob))
            {

                CloudBlockBlob blob = (CloudBlockBlob)item;

                blob.FetchAttributes();

                foreach (var metaDataItem in blob.Metadata)
                {
                    dictionary.Add(metaDataItem.Key, metaDataItem.Value);
                }

                if (dictionary.Where(r=>r.Key == "FlightNo" && r.Value == FlightNo).Any())
                {
                    if (dictionary.Where(r => r.Key == "FlightDate" && r.Value == FlightDate).Any())
                    {
                        if (dictionary.Where(r => r.Key == "FromAirport" && r.Value == FromAirport).Any())
                        {
                            if (dictionary.Where(r => r.Key == "ToAirport" && r.Value == ToAirport).Any())
                            {
                                if (dictionary.Where(r => r.Key == "ToAirport" && r.Value == ToAirport).Any())
                                {
                                    retList.Add(new BlobStorage()
                                    {
                                        Filename = blob.Name,
                                        BlobType = blob.BlobType.ToString(),
                                        LastModified = (DateTimeOffset)blob.Properties.LastModified,
                                        ContentType = blob.Properties.ContentType,
                                        Length = blob.Properties.Length,
                                        uri = RemoveSecondary(blob.StorageUri.ToString()),
                                        FlightNo = dictionary.Where(r => r.Key == "FlightNo").Select(r => r.Value).SingleOrDefault(),
                                        Fixture = dictionary.Where(r => r.Key == "FixtureNo").Select(r => r.Value).SingleOrDefault(),
                                        FlightDate = dictionary.Where(r => r.Key == "FlightDate").Select(r => r.Value).SingleOrDefault(),
                                        FromAirport = dictionary.Where(r => r.Key == "FromAirport").Select(r => r.Value).SingleOrDefault(),
                                        ToAirport = dictionary.Where(r => r.Key == "ToAirport").Select(r => r.Value).SingleOrDefault()
                                    });

                                }
                            }
                        }
                    }
                }

                dictionary.Clear();
            }
        }

谢谢。斯科特

【问题讨论】:

  • 不完全确定您的问题是什么。但是...搜索 blob 元数据不是一种有效的操作,因为没有索引。您可能会考虑使用某种类型的数据库来保存您的元数据,以方便查询。
  • 索引 Blob 元数据并使用 Azure 搜索现在使搜索 Blob 元数据成为一项非常高效的操作。

标签: c# azure azure-blob-storage


【解决方案1】:

公认的答案效率极低,循环加载每个 Blob 及其关联的元数据以检查值在任何合理的数据量下都不会很好地执行。

可以使用 Azure 搜索来搜索 Blob 元数据。可以创建包含 Blob 自定义元数据的搜索索引。

以下综合文章说明了一切:

Indexing Documents in Azure Blob Storage with Azure Search
Searching Blob storage with Azure Search

【讨论】:

【解决方案2】:

虽然仍处于预览阶段,但您现在可以使用 Blob 索引对 Blob 元数据(标签)进行查询搜索。

在找到所需内容之前,您无需遍历所有 blob。

这是来自full article的sn-p:

Blob 索引(一种托管二级索引,允许您存储多维对象属性来描述 Azure Blob 存储的数据对象)现在提供预览版。 Blob 索引建立在 Blob 存储之上,可为您的所有工作负载提供一致的可靠性、可用性和性能。 Blob Index 提供原生对象管理和过滤功能,可以根据数据上设置的属性标签对数据进行分类和查找。

【讨论】:

  • 这可能应该是 2020 年的答案。但是,blob 索引确实需要额外费用。
【解决方案3】:

如果我理解正确,您想搜索包含您提到的所有 5 个项目元数据的 blob。您可以使用以下代码来执行此操作。我自己测试了一下,它工作正常。

var connectionString = "storage connection string";
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(connectionString);
CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
CloudBlobContainer container = blobClient.GetContainerReference("container");
var blobs = container.ListBlobs();
var blobList = new List<CloudBlockBlob>();
foreach (var item in blobs)
 {
      CloudBlockBlob blob = (CloudBlockBlob)item;

      blob.FetchAttributes();
      if (blob.Metadata.Contains(new KeyValuePair<string, string>("FlightNo", "FlightNoValue")) &&
         blob.Metadata.Contains(new KeyValuePair<string, string>("FlightDate", "FlightDateValue")) &&
         blob.Metadata.Contains(new KeyValuePair<string, string>("FromAirport", "FromAirportValue")) &&
         blob.Metadata.Contains(new KeyValuePair<string, string>("ToAirport", "ToAirportValue")) && 
         blob.Metadata.Contains(new KeyValuePair<string, string>("FixtureNo", "FixtureNoValue")))
      {
          blobList.Add(blob);
      }

【讨论】:

  • 谢谢。将测试并返回给您。抱歉耽搁了。赞赏。苏格兰人
  • 如果您不需要检查元数据的值,我们可以使用blob.Metadata.ContainsKey("KeyName")
  • 完美运行。抱歉耽搁了。非常感谢斯科特
【解决方案4】:

您不能直接搜索元数据,但您可以使用tags,从实际角度来看,它们与元数据有点相似。标签由存储索引,搜索匹配 blob 的代码非常简单:

    var query = $"@container = 'invoices' AND brand = 'volvo'";
    
    await foreach (var blob in blobServiceClient.FindBlobsByTagsAsync(query))
    {
        Console.WriteLine($"Container: {blob.BlobContainerName}, Blob: {blob.BlobName}");
    }

【讨论】:

    猜你喜欢
    • 2015-12-01
    • 2020-06-15
    • 1970-01-01
    • 1970-01-01
    • 2019-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多