Search code examples
c#azureazure-blob-storageazure-storage

How to get blobs from azure storage by prefix while ignoring virtual folders?


I have created an "images" container inside azure blob storage. I'm resizing images into "S, XL,M, etc" then put this images using this blob name structure "imageSize/imageId-imageName.extension"

lets imagine that i have this structure inside images container

- s
     2456-earth.png
     3457-boat.jpeg
- m
     2456-earth.png
     4267-flower.jpeg

I want to use imageId as the prefix to get all blobs that start with that imageId. the probleme is that they are just virtual folders so the blob names in reality are

s/2456-earth.png
s/3457-boat.jpeg
m/2456-earth.png
m/4267-flower.jpeg

I have tried this code but it won't work:

var blobs = containerClient.GetBlobsAsync(BlobTraits.None, BlobStates.None, prefix: "2456");

I foud a solution like this:

var sizes = new List<string>() { "xs", "s", "m", "l", "xl" };
foreach (var size in sizes) {
   var blobs = containerClient.GetBlobsAsync(BlobTraits.None, BlobStates.None, prefix: $"{size}/2456");
   // Do something here
}

The probleme is performance issues because I'm doing multiple requests, also I want to avoid looping throught an array of sizes to make code simple.

Is there a way to get blobs by prefix while ignoring virtual folders?


Solution

  • Is there a way to get blobs by prefix while ignoring virtual folders?

    No.

    You might have to rethink the way you store the images. A naming convention like [id]-[size]-[name].[extension] is a better fit but of course it depends on what other search patterns you need.

    Another way is to use blob index tags. It means applying tags like [size] and [id] to your blobs. You can then perform a query using those tags:

    public static async Task FindBlobsbyTags(BlobServiceClient serviceClient)
    {
        string query = @"""Id"" = '2456'";
    
        // Find Blobs given a tags query
        Console.WriteLine("Find Blob by Tags query: " + query + Environment.NewLine);
    
        List<TaggedBlobItem> blobs = new List<TaggedBlobItem>();
        await foreach (TaggedBlobItem taggedBlobItem in serviceClient.FindBlobsByTagsAsync(query))
        {
            blobs.Add(taggedBlobItem);
        }
    
        foreach (var filteredBlob in blobs)
        {
            
            Console.WriteLine($"BlobIndex result: ContainerName= {filteredBlob.BlobContainerName}, " +
                $"BlobName= {filteredBlob.BlobName}");
        }
    
    }
    

    For an overview of how to build queries see the docs