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件を超えません
勘違い点
上記ページに単一の 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
は指定しておけ- 手抜きダメ絶対