29

Microsoft.WindowsAzure.StorageClient を使用して、Azure ストレージの BLOB を操作しています。ユーザーがアップロードされたファイルをリストし、それらを変更/削除する必要があるところまで来ました。1 つのコンテナーに多くのファイルがあるため、Azure ストレージ サービスにクエリを実行して目的のファイルのみを返す最適な方法は何ですか。また、ページングを実装できるように、特定の数のブロブのみを返すことができるようにしたいと考えています。

CloudBlobContainer に ListBlobs というメソッドがありますが、コンテナ内のすべてのブロブを返しているようです。それは私にはうまくいきません。

このトピックについて多くのことを検索しましたが、役立つものは何も見つかりませんでした。このリンクは基本のみを示しています。

- - - - - 編集

以下の私の答えは、ブロブを遅延して取得するのではなく、コンテナー内のすべてのブロブを取得してから、結果をフィルター処理します。現在、ブロブを遅延取得するための解決策はありません。

4

8 に答える 8

34

メソッド ListBlobs は、そのコンテナー内の BLOB を遅延して取得します。そのため、リストをループする (または ToList やその他のメソッドでオブジェクトを具体化する) まで実行されない、そのメソッドに対するクエリを作成できます。

いくつかの例で物事がより明確になります。Azure ストレージ アカウント内のコンテナーへの参照を取得する方法がわからない場合は、このチュートリアルをお勧めします。

最終更新日で並べ替え、ページ番号 2 を取得 (1 ページあたり 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
}
于 2013-01-21T14:14:49.747 に答える
4

編集

現在プレビュー段階にあるのは、 Azure Storage の BLOB インデックスです。これは、BLOB (新規または既存) に追加できるメタデータのマネージド インデックスです。これにより、疑似インデックス作成のためにクリエイティブなコンテナ名を使用したり、自分でセカンダリ インデックスを維持したりする必要がなくなります。

元の答え

特定の結果を返す場合、考えられるオプションの 1 つは、BLOB やコンテナーのプレフィックスを使用して、格納しているものに効果的にインデックスを付けることです。たとえば、ブロブを追加するときに日付と時刻のプレフィックスを付けたり、ユーザーのプレフィックスを付けたりすることができます。これは、ブロブをどのように "インデックス化" するかについてのユース ケースによって異なります。次に、このプレフィックスまたはその一部を ListBlobs[Segmented] 呼び出しで使用して、特定の結果を返すことができます。明らかに、最も一般的な要素を最初に配置してから、より具体的な要素を配置する必要があります。例:

2016_03_15_10_15_blobname

これにより、2016 年のすべての BLOB、または 2016 年 3 月の BLOB などを取得できますが、複数の呼び出しを行わなくても、どの年でも 3 月の BLOB を取得することはできません。

これの欠点は、BLOB のインデックスを再作成する必要がある場合、BLOB を削除して新しい名前で再作成する必要があることです。

通常、ページングには、ページングの実装に使用できる継続トークンを提供する ListBlobsSegmented メソッドを使用できます。つまり、ページをスキップする必要がある場合は、実際の結果の最後のセットが中断されたところから開始することによってのみ機能するため、あまり役に立ちません。これに関する 1 つのオプションは、スキップする必要があるページ数を計算し、これらを取得して破棄し、実際に必要なページを取得することです。各コンテナーに多数のブロブがある場合、これはかなり非効率になる可能性があります....

これをフェイルバック方法として使用することもできます。ページごとのアプローチを使用し、ユーザーが 1 つのページから次のページに順番にクリックしている場合は継続トークンを保存します。または、潜在的に BLOB 名をキャッシュし、そこから独自のページングを行うこともできます。

これら 2 つのアプローチを組み合わせることもできます。たとえば、「インデックス」でフィルタリングしてから結果をページングします。

于 2016-03-15T15:02:16.937 に答える