検索インデックスを使用してデータをクエリする場合、定義済みのソート方法を使用するか、ソート方法を指定できます。このようにして、クエリ条件を満たす行は、事前に定義または指定した順序に基づいて返されます。レスポンスに多数の行が含まれている場合は、limit パラメーターと offset パラメーターを設定するか、トークンを使用して必要なデータを特定できます。
シナリオ
カテゴリ | 方法 | 機能 | シナリオ |
ソート | 検索インデックスの作成時にソート方法を事前に定義する | デフォルトでは、検索インデックスのデータは、IndexSort パラメーターで指定された事前ソート設定に基づいてソートされます。IndexSort パラメーターで指定された事前ソート設定により、クエリ条件を満たす行が返されるデフォルトの順序が決まります。 | |
データをクエリする際にソート方法を指定する | ScoreSort を使用して、BM25 ベースのキーワード関連性スコアに基づいてクエリ結果をソートできます。ScoreSort は、全文検索などのシナリオに適しています。 | ||
PrimaryKeySort を使用して、プライマリキー値に基づいてクエリ結果をソートできます。PrimaryKeySort は、データの一意の識別子に基づいてデータをソートする場合に適しています。 | |||
FieldSort を使用して、1 つ以上の列の値に基づいてクエリ結果をソートできます。FieldSort は、売上高やページビューなどのプロパティに基づいてデータをソートする場合に適しています。ほとんどの場合、FieldSort は、eコマース、ソーシャルネットワーキング、メディアアセットなどの業界で使用されます。 | |||
GeoDistanceSort を使用して、地理的な場所によってクエリ結果をソートできます。GeoDistanceSort は、特定の場所からの距離に基づいてデータをソートする場合に適しています。ほとんどの場合、GeoDistanceSort は、マッピングや物流などの業界で使用されます。たとえば、場所の周りのレストランを場所からの距離に基づいてソートできます。 複数値フィールド (配列フィールドやネストフィールドなど) の mode パラメーターを FieldSort で指定して、クエリ結果のソートに使用する要素を決定できます。 | |||
ページング | データをクエリする際にページング方法を指定する | レスポンスの行数が 100,000 未満の場合は、この方法を使用してページにジャンプできます。 | |
この機能を使用すると、データはページごとに返され、後方へのみページングできます。前方へページングする場合は、トークンはクエリ中に永続的に有効であるため、前のトークンをキャッシュして使用できます。 |
検索インデックスの作成時にソート方法を指定する
デフォルトでは、検索インデックスのデータは IndexSort パラメーターの値に基づいてソートされます。検索インデックスを使用してデータをクエリする場合、IndexSort パラメーターの値によって、一致するデータが返されるデフォルトの順序が決まります。
検索インデックスを作成するときに、IndexSort パラメーターを設定することで事前ソート設定を指定できます。事前ソート設定を指定しない場合、検索インデックスのデータはプライマリキーでソートされます。
検索インデックスの事前ソート方法として、PrimaryKeySort または FieldSort を指定できます。PrimaryKeySort はプライマリキーによるソートを示し、FieldSort はフィールド値によるソートを示します。
ネストフィールドを含む検索インデックスは、インデックスの事前ソートをサポートしていません。
データをクエリする際にソート方法を指定する
ソートは、enableSortAndAgg パラメーターが true に設定されているフィールドに対してのみ有効にできます。
クエリごとにソート方法を指定できます。検索インデックスベースのクエリは、次のソート方法をサポートしています。優先順位の異なる複数のソート方法を指定することもできます。
ScoreSort
ScoreSort を使用して、BM25 ベースのキーワード関連性スコアに基づいてクエリ結果をソートできます。ScoreSort は、全文検索などのシナリオに適しています。
一致するデータをキーワード関連性スコアでソートする前に、ScoreSort のパラメーターを設定する必要があります。設定しない場合、一致するデータは、IndexSort パラメーターで指定された事前ソート設定に基づいてソートされます。
SearchQuery searchQuery = new SearchQuery();
// BM25 ベースのキーワード関連性スコアに基づいてクエリ結果をソートします。
searchQuery.setSort(new Sort(Arrays.asList(new ScoreSort())));
PrimaryKeySort
PrimaryKeySort を使用して、プライマリキーの値に基づいてクエリ結果をソートできます。
SearchQuery searchQuery = new SearchQuery();
searchQuery.setSort(new Sort(Arrays.asList(new PrimaryKeySort()))); // クエリ結果を昇順にソートします。
//searchQuery.setSort(new Sort(Arrays.asList(new PrimaryKeySort(SortOrder.DESC)))); // クエリ結果を降順にソートします。
FieldSort
FieldSort を使用して、1 つ以上の特定の列の値に基づいてクエリ結果をソートできます。
単一列の値に基づいてクエリ結果をソートする
FieldSort を使用して、特定の列の値に基づいてクエリ結果をソートできます。
SearchQuery searchQuery = new SearchQuery();
// "col" 列の値に基づいてクエリ結果を昇順にソートします。
searchQuery.setSort(new Sort(Arrays.asList(new FieldSort("col", SortOrder.ASC))));
複数列の値に基づいてクエリ結果をソートする
特定の順序で 2 つの列の値に基づいてクエリ結果をソートして、一致するデータが返される順序を決定することもできます。
SearchQuery searchQuery = new SearchQuery();
// "col1" 列の値に基づいて昇順にソートし、次に "col2" 列の値に基づいて昇順にソートします。
searchQuery.setSort(new Sort(Arrays.asList(
new FieldSort("col1", SortOrder.ASC), new FieldSort("col2", SortOrder.ASC))));
補足列の値に基づいてクエリ結果をソートする
Long、Double、または Date 型の列値に基づいてデータをソートする場合、missingField パラメーターを設定して、元の列にデータがない場合に使用する同じデータ型の列を補足列として指定できます。
/**
* Col_Long 列の値に基づいてクエリ結果を降順にソートします。Long 型の Col_Long 列のデータがない場合は、同じデータ型の Col_Long_sec 列をソート用の補足列として使用できます。
*/
SearchQuery searchQuery = new SearchQuery();
FieldSort fieldSort = new FieldSort("Col_Long");
// Col_Long 列のデータがない場合のソート用の補足列として Col_Long_sec 列を指定します。
fieldSort.setMissingField("Col_Long_sec");
fieldSort.setOrder(SortOrder.DESC);
複数値フィールドの指定された要素に基づいてクエリ結果をソートする
配列フィールドやネストフィールドなどの複数値フィールドの mode パラメーターを指定して、クエリ結果のソートに使用する要素を決定できます。
配列フィールドの mode パラメーターを指定して、クエリ結果のソートに使用する要素を決定できます。
// doc1 行と doc2 行には、配列型の field1 列が含まれています。doc1 行の field1 列の値は [2,3] で、doc2 行の field1 列の値は [1,3,4] です。
// mode パラメーターを指定して、2 つの行のソートに使用する配列フィールドの要素を決定できます。
{
// mode パラメーターを SortMode.MAX に設定すると、配列フィールドの最大要素を使用して行がソートされます。この例では、doc1 行の 3 と doc2 行の 4 を使用して 2 つの行がソートされ、ソート結果は doc2 と doc1 になります。
FieldSort fieldSort = new FieldSort("field1", SortOrder.DESC);
fieldSort.setMode(SortMode.MAX);
}
{
// mode パラメーターを SortMode.MIN に設定すると、配列フィールドの最小要素を使用して行がソートされます。この例では、doc1 行の 2 と doc2 行の 1 を使用して 2 つの行がソートされ、ソート結果は doc1 と doc2 になります。
FieldSort fieldSort = new FieldSort("field1", SortOrder.DESC);
fieldSort.setMode(SortMode.MIN);
}
ネストフィールドの mode パラメーターを指定して、子行のソートに使用する要素を決定することもできます。
// doc1 行と doc2 行には、ネスト型の field1 列が含まれています。
// doc1 行の field1 列の値は [{"name":"b", "age":1},{"name":"a", "age":7}] です。
// doc2 行の field1 列の値は [{"name":"a", "age":1},{"name":"c", "age":1},{"name":"d", "age":5}] です。
{
// mode パラメーターを指定して、子行のソートに使用する 2 つの行のネストフィールドの要素を決定できます。
// mode パラメーターを SortMode.MAX に設定すると、ネストフィールドの最大要素を使用して行がソートされます。この例では、doc1 行の 7 と doc2 行の 5 を使用して age 列で 2 つの行がソートされ、ソート結果は doc1 と doc2 になります。
FieldSort fieldSort = new FieldSort("field1.age", SortOrder.DESC);
fieldSort.setMode(SortMode.MAX);
String path = "field1";
NestedFilter nestedFilter = new NestedFilter(path, QueryBuilders.matchAll().build());
fieldSort.setNestedFilter(nestedFilter);
}
{
// mode パラメーターを指定して、age 列の値が 1 である子行のソートに使用する 2 つの行のネストフィールドの要素を決定できます。
{
// mode パラメーターを SortMode.MAX に設定すると、ネストフィールドの最大要素を使用して行がソートされます。この例では、doc1 行の "b" と doc2 行の "c" を使用して name 列で 2 つの行がソートされ、ソート結果は doc2 と doc1 になります。
FieldSort fieldSort = new FieldSort("field1.name", SortOrder.DESC);
fieldSort.setMode(SortMode.MAX);
String path = "field1";
NestedFilter nestedFilter = new NestedFilter(path, QueryBuilders.term("field1.age",1).build());
fieldSort.setNestedFilter(nestedFilter);
}
{
// mode パラメーターを SortMode.MIN に設定すると、ネストフィールドの最小要素を使用して行がソートされます。この例では、doc1 行の "b" と doc2 行の "a" を使用して name 列で 2 つの行がソートされ、ソート結果は doc1 と doc2 になります。
FieldSort fieldSort = new FieldSort("field1.name", SortOrder.DESC);
fieldSort.setMode(SortMode.MIN);
String path = "field1";
NestedFilter nestedFilter = new NestedFilter(path, QueryBuilders.term("field1.age",1).build());
fieldSort.setNestedFilter(nestedFilter);
}
}
GeoDistanceSort
GeoDistanceSort を使用して、地理的な場所によってクエリ結果をソートできます。
SearchQuery searchQuery = new SearchQuery();
// Geopoint 型の geo 列の値から座標ペア (0, 0) までの距離に基づいて結果をソートします。
Sort.Sorter sorter = new GeoDistanceSort("geo", Arrays.asList("0, 0"));
searchQuery.setSort(new Sort(Arrays.asList(sorter)));
ページング方法を指定する
limit パラメーターと offset パラメーターを設定するか、トークンを使用してレスポンスの行をページングできます。
limit パラメーターと offset パラメーターを設定する
レスポンスの行の総数が 100,000 未満の場合は、limit パラメーターと offset パラメーターを設定して行をページングできます。limit パラメーターと offset パラメーターの値の合計は 100,000 を超えることはできません。limit パラメーターの最大値は 100 です。
limit パラメーターの最大値を増やす方法については、「検索インデックス機能の Search オペレーションを呼び出してデータをクエリする際に、limit パラメーターの値を 1000 に増やすにはどうすればよいですか?」を参照してください。
limit パラメーターと offset パラメーターの値を指定しない場合は、デフォルト値が使用されます。limit パラメーターのデフォルト値は 10 です。offset パラメーターのデフォルト値は 0 です。
SearchQuery searchQuery = new SearchQuery();
searchQuery.setQuery(new MatchAllQuery());
// 1 ページあたり最大 100 行を返します。
searchQuery.setLimit(100);
// 100 行目をスキップします。
searchQuery.setOffset(100);
トークンを使用する
この方法ではページングの深さに制限がないため、深いページングにはトークンを使用することをお勧めします。
Tablestore がクエリ条件を満たすすべてのデータを読み取れない場合、Tablestore は nextToken を返します。nextToken を使用して、後続のデータの読み取りを続行できます。
デフォルトでは、トークンを使用する場合、後方へのみページングできます。ただし、トークンはクエリ中に有効であるため、前のトークンをキャッシュして使用することで前方へページングできます。
nextToken を永続化するか、フロントエンドページに転送する必要がある場合は、Base64 を使用して nextToken を文字列にエンコードできます。トークンは文字列ではありません。new String(nextToken)
を使用してトークンを文字列にエンコードすると、トークンに関する情報が失われます。
トークンを使用する場合、ソート方法は前のリクエストで使用された方法と同じです。Tablestore は、デフォルトでは IndexSort パラメーターに基づいて、または指定した方法に基づいてデータをソートします。トークンを使用する場合は、ソート方法を指定できません。トークンを使用する場合は、offset パラメーターを設定できません。データはページごとに順番に返されます。これにより、クエリが遅くなります。
ネストフィールドを含む検索インデックスは、インデックスの事前ソートをサポートしていません。ページングが必要で、ネストフィールドを含む検索インデックスを使用してデータをクエリする場合は、クエリ条件でソート方法を指定して、指定された順序でデータを返す必要があります。指定しない場合、クエリ条件を満たすデータの一部のみが返されるときに、Tablestore は nextToken を返しません。
private static void readMoreRowsWithToken(SyncClient client) {
// クエリを作成します。
SearchQuery searchQuery = new SearchQuery();
searchQuery.setQuery(new MatchAllQuery());
// クエリ条件を満たす行の総数が返されるように指定します。
searchQuery.setGetTotalCount(true);
// データテーブルの名前を指定します。例: sampleTable。次に、検索インデックスの名前を指定します。例: sampleSearchIndex。検索インデックスの名前を取得するには、Tablestore コンソールで、または Tablestore SDK を使用して検索インデックスのリストをクエリします。Tablestore コンソールで検索インデックスのリストをクエリする場合は、[テーブルの管理] ページの [インデックス] タブでリストを表示できます。
SearchRequest searchRequest = new SearchRequest("<TABLE_NAME>", "<SEARCH_INDEX_NAME>", searchQuery);
// 最初のページのデータをクエリします。
SearchResponse resp = client.search(searchRequest);
if (!resp.isAllSuccess()) {
throw new RuntimeException("not all success"); // 全て成功ではありません。
}
List<Row> rows = resp.getRows();
// nextToken がレスポンスに存在する場合は、後続のデータをクエリします。nextToken 値がレスポンスで null の場合、すべてのデータが読み取られます。
while (resp.getNextToken()!=null) {
// nextToken 値をクエリします。
byte[] nextToken = resp.getNextToken();
{
// nextToken を永続化するか、フロントエンドページに転送する必要がある場合は、Base64 を使用して nextToken を文字列にエンコードできます。
// トークンは文字列ではありません。new String(nextToken) を使用してトークンを文字列にエンコードすると、トークンに関する情報が失われます。
String tokenAsString = Base64.toBase64String(nextToken);
// 文字列をバイトにデコードします。
byte[] tokenAsByte = Base64.fromBase64String(tokenAsString);
}
// このリクエストのトークンを前のレスポンスの nextToken 値に設定します。
searchRequest.getSearchQuery().setToken(nextToken);
resp = client.search(searchRequest);
if (!resp.isAllSuccess()) {
throw new RuntimeException("not all success"); // 全て成功ではありません。
}
rows.addAll(resp.getRows());
}
System.out.println("RowSize: " + rows.size());
// 一致する行の総数 (返された行の数ではなく) が表示されるように指定します。
System.out.println("TotalCount: " + resp.getTotalCount());
}
FAQ
関連情報
検索インデックスを使用してデータをクエリする場合、次のクエリ方法を使用できます。タームクエリ、タームズクエリ、すべて一致クエリ、一致クエリ、一致フレーズクエリ、プレフィックスクエリ、範囲クエリ、ワイルドカードクエリ、地理クエリ、KNNベクタクエリ、ブールクエリ、ネストクエリ、存在クエリ。検索インデックスを作成した後、検索インデックスによって提供されるクエリ方法を使用して、ビジネス要件に基づいて複数のディメンションからデータをクエリできます。
ソート機能とページング機能を使用して、クエリ条件を満たす行をソートまたはページングできます。詳細については、「ソートとページングの実行」を参照してください。
折りたたみ (個別) 機能を使用して、特定の列に基づいて結果セットを折りたたむことができます。このようにして、指定されたタイプのデータはクエリ結果に一度だけ表示されます。詳細については、「折りたたみ (個別)」を参照してください。
テーブルのデータを分析する場合は、Search オペレーションを呼び出して集計機能を使用するか、SQL クエリ機能を使用できます。たとえば、最大値と最小値、値の合計、行数をクエリできます。詳細については、「集計」および「SQL クエリ」を参照してください。
行をソートする必要なく、クエリ条件を満たすすべての行を取得する場合は、ParallelScan オペレーションと ComputeSplits オペレーションを呼び出して並列スキャン機能を使用できます。詳細については、「並列スキャン」を参照してください。