プログラムの事とか

お約束ですが「掲載内容は私個人の見解です」

Azure Table Storage のContinuationTokenを盛大に勘違いしていた件

現在進行形でやらかしています。これから修正しなきゃいけないのでざっくりやらかしたことをメモ(調査も検証もなし)

コード

async Task<TableEntity[]> Get(long id1,long id2){
    var tableClient = _storageAccount.CreateCloudTableClient();
    var table1 = tableClient.GetTableReference("Table1");
    var table1Query = new TableQuery<TableEntity>();
    table1Query.FilterString = TableQuery.CombineFilters(
        TableQuery.GenerateFilterConditionForLong("Id1", QueryComparisons.Equal, id1),
        TableOperators.And,
        TableQuery.GenerateFilterConditionForLong("Id2", QueryComparisons.Equal, Id2));
    var entities = await table1.ExecuteQuerySegmentedAsync(table1Query, null);
    return entities.ToArray();
}

こんな感じの関数つくります

  • Table1というテーブルからId1,Id2を条件に全件取得しようとしています (PartitionKey指定していないのがそもそも・・・とかそういうのは無視で)
  • Id1,Id2を条件にした場合データの件数は多くても10件を超えません

勘違い点

docs.microsoft.com

上記ページに単一の EGT で最大 100 個のエンティティを処理できますと書いてあります。ほかにもTable Strorage関連のドキュメントなどでは100という数字(上限)がよく出てくるような気がします (気がしているだけ)

そこで、考えることを常にやめている私は「100件超える可能性があるときはContinuationToken使ってループ書こう」という結論になってしまいました

現象

上記関数はTable1のレコード数が100件(くらい)までは問題なく動きます。しかしデータ数が増えていくと後半の該当データは1回目のクエリでは帰ってこなくなります (そしてentities.ContinuationTokenがnullではなくなります)

今回は4件のデータを取ってくるのに2~3回のループが必要でした

どーいうこと?

面倒なので調べていません。予想で書きます

100件(たぶん)の制限は返ってくるデータ数ではなくAPIが読み込むデータ数なんだと思います。PartitionKeyを指定しない場合は全件検索(?)になるとかどこかに書いてあった気もしますし、今回は指定していなかったのでAPIは全件読み込むつもりでいるのでしょう 。そして最初の100件(くらい)から条件に合った数件のデータのみを返してきたんだと思います。PartitionKeyを指定した場合はPartitionKey内のデータのみを見るんでしょうね (きっとどこかにそういうドキュメントがあるんだろうな~)

私は同じような処理(件数が少ないことが分かっているのでループを書かない)を結構書いてしまっていますが、問題は今まで起きませんでした。それはほかの処理では必ずPartitionKeyを指定していたからで、いずれほかでも同じ問題が出てくるんじゃないかなー、と遠い目をしています

結論

  • PartitionKeyは指定しておけ
  • 手抜きダメ絶対