Tablestore SDK for Java を使用したネストされたクエリは、子行の境界を維持しながら Nested フィールド内のデータに一致させ、一致した子行を返すことができます。
前提条件
Tablestore SDK for Java をインストールし、クライアントを初期化します。
機能説明
ネストされたクエリは、Nested フィールド内の子行をクエリします。Nested フィールド内の各子行は、そのフィールド間の関係を独立して保持します。Nested フィールドのサブフィールドを直接クエリすることはできません。代わりに、サブクエリを NestedQuery オブジェクトでラップします。
NestedQuery.path は、クエリ対象のネストされたフィールドのパスを指定します。サブクエリ内のフィールド名は完全なパスを使用する必要があります。サブクエリは任意の Query 型にすることができます。複数レベルのネストされたフィールドをクエリするには、path をターゲットのネストされたフィールドの完全なパスに直接設定するか、NestedQuery オブジェクトをネストして各レベルをクエリします。
複数の条件を同じ子行で満たす必要があるかどうかは、NestedQuery と BoolQuery の組み合わせ方によって決まります:
同じ子行が複数の条件を満たす必要がある場合は、子条件を含む
BoolQueryを 1 つのNestedQueryのサブクエリとして設定します。異なる子行が条件を個別に満たすことを許可する場合は、条件ごとに 1 つの
NestedQueryを作成し、外部のBoolQueryでネストされたクエリを組み合わせます。
search を呼び出して、ネストされたクエリを実行します。クエリ条件では、ネストされたフィールドのパス、サブクエリ、およびスコアモードを指定します。
SearchResponse search(SearchRequest request)
次の例では、items ネストされたフィールド内で、items.keyword フィールドが tablestore に等しい子行をクエリします。このクエリは最大 10 行と一致した総数を返します。
String tableName = "example_table";
String indexName = "example_index";
TermQuery termQuery = new TermQuery();
termQuery.setFieldName("items.keyword");
termQuery.setTerm(ColumnValue.fromString("tablestore"));
NestedQuery nestedQuery = new NestedQuery();
nestedQuery.setPath("items");
nestedQuery.setQuery(termQuery);
nestedQuery.setScoreMode(ScoreMode.None);
SearchQuery searchQuery = new SearchQuery();
searchQuery.setQuery(nestedQuery);
searchQuery.setLimit(10);
searchQuery.setTrackTotalCount(SearchQuery.TRACK_TOTAL_COUNT);
SearchRequest request = new SearchRequest(tableName, indexName, searchQuery);
SearchResponse response = client.search(request);
System.out.println(response.getTotalCount());
System.out.println(response.getRows());
パラメーター
検索リクエスト
request は、以下のパラメーターを含む SearchRequest オブジェクトです。
|
名前 |
型 |
説明 |
|
tableName (必須) |
String |
データテーブルの名前。 |
|
indexName (必須) |
String |
検索インデックスの名前。 |
|
searchQuery (必須) |
SearchQuery |
クエリ条件と一般的なクエリ設定。 |
|
columnsToGet (任意) |
SearchRequest.ColumnsToGet |
返却する列。このパラメーターが設定されていない場合、プライマリキー列のみが返されます。 |
|
timeoutInMillisecond (任意) |
int |
リクエストレベルのクエリタイムアウト (ミリ秒単位)。デフォルト値は |
|
routingValues (任意) |
|
カスタムルートフィールドに対応するプライマリキーの値。カスタムルーティングが設定されていない場合は、このパラメーターを設定しないでください。 |
クエリ設定
request.searchQuery は、以下のパラメーターを含む SearchQuery オブジェクトです。
|
名前 |
型 |
説明 |
|
query (必須) |
Query |
クエリ条件。ネストされたクエリの場合、このパラメーターを |
|
offset (任意) |
Integer |
クエリの開始位置。 |
|
limit (任意) |
Integer |
返却する最大行数。このパラメーターを |
|
collapse (任意) |
Collapse |
指定されたフィールドで結果を重複排除するフィールドの折りたたみ設定。設定の詳細については、「クエリ結果の折りたたみ」をご参照ください。 |
|
sort (任意) |
Sort |
結果のソート順。設定の詳細については、「結果のソートとページ分割」をご参照ください。 |
|
trackTotalCount (任意) |
int |
カウントする一致行の予想最大数。デフォルト値は |
|
filter (任意) |
SearchFilter |
|
|
aggregationList (任意) |
|
集約設定。設定の詳細については、「集約」をご参照ください。 |
|
groupByList (任意) |
|
グループ化設定。設定の詳細については、「集約」をご参照ください。 |
|
token (任意) |
byte[] |
ページネーショントークン。前の応答の |
ネストされたクエリの条件
request.searchQuery.query は、以下のパラメーターを含む NestedQuery オブジェクトです。
|
名前 |
型 |
説明 |
|
path (必須) |
String |
クエリ対象のネストされたフィールドのパス。複数レベルのネストされたフィールドの場合、このパラメーターをターゲットのネストされたフィールドの完全なパス (例: |
|
query (必須) |
Query |
|
|
scoreMode (必須) |
ScoreMode |
複数の子行が一致した場合の親行のスコアリングモード。 |
|
innerHits (任意) |
InnerHits |
一致した子行の返却、ソート、ページ分割、およびハイライトに関する設定。このパラメーターを省略した場合、一致した子行の詳細は返されません。 |
|
weight (任意) |
float |
クエリの重み。デフォルト値は |
子行の返却設定
request.searchQuery.query.innerHits は、以下のパラメーターを含む InnerHits オブジェクトです。
|
名前 |
型 |
説明 |
|
sort (任意) |
Sort |
一致した子行のソート順。 |
|
offset (任意) |
Integer |
一致した子行を返し始める開始位置。 |
|
limit (任意) |
Integer |
返却する一致した子行の最大数。デフォルト値は |
|
highlight (任意) |
Highlight |
一致した子行のハイライト設定。ハイライトをサポートするフィールドとパラメーターについては、「概要とハイライト」をご参照ください。 |
返却される列
request.columnsToGet は、以下のパラメーターを含む SearchRequest.ColumnsToGet オブジェクトです。
|
名前 |
型 |
説明 |
|
columns (任意) |
|
返却する属性列。このパラメーターは、 |
|
returnAll (任意) |
boolean |
データテーブルからすべての属性列を返却するかどうかを指定します。デフォルト値は |
|
returnAllFromIndex (任意) |
boolean |
インデックス付けされたすべての属性列を返却するかどうかを指定します。デフォルト値は |
戻り値
検索応答
search は SearchResponse オブジェクトを返します。次の表に、コアフィールドを示します。
|
名前 |
型 |
説明 |
|
totalCount |
long |
一致した行数。 |
|
rows |
|
このクエリによって返された行。 |
|
searchHits |
|
クエリヒット。 |
|
nextToken |
byte[] |
次のページのトークン。 |
|
isAllSuccess |
boolean |
すべてのインデックスパーティションが正常にクエリされたかどうかを示します。 |
検索ヒット
response.searchHits[] は、以下のコアフィールドを含む SearchHit オブジェクトです。
|
名前 |
型 |
説明 |
|
row |
Row |
一致した行または子行。 |
|
score |
Double |
関連性スコア。 |
|
offset |
Integer |
元の配列におけるネストされた子行の位置。 |
|
highlightResultItem |
HighlightResultItem |
ハイライト結果。 |
|
searchInnerHits |
|
ネストされたフィールドのパスでグループ化された一致した子行。マップを取得するには |
ネストされたヒット
response.searchHits[].searchInnerHits には、以下のフィールドを持つ SearchInnerHit の値が含まれます。
|
名前 |
型 |
説明 |
|
path |
String |
ネストされたフィールドのパス。 |
|
subSearchHits |
|
一致した子行。 |
シナリオ例
複数レベルのネストされたフィールドのクエリ
複数レベルのネストされたフィールドをクエリするには、path をターゲットのネストされたフィールドの完全なパスに設定し、サブクエリでサブフィールドの完全なパスを指定します。次の例では、items.details.name が beta に等しい行をクエリします。
TermQuery termQuery = new TermQuery();
termQuery.setFieldName("items.details.name");
termQuery.setTerm(ColumnValue.fromString("beta"));
NestedQuery nestedQuery = new NestedQuery();
nestedQuery.setPath("items.details");
nestedQuery.setQuery(termQuery);
nestedQuery.setScoreMode(ScoreMode.None);
SearchQuery searchQuery = new SearchQuery();
searchQuery.setQuery(nestedQuery);
同じ子行が複数の条件を満たす必要がある場合
複数の子条件を含む BoolQuery を 1 つの NestedQuery のサブクエリとして設定します。次の例では、items 内の同じ子行が、items.keyword の値として tablestore を持ち、かつ items.number フィールドを持つ必要があります。
TermQuery termQuery = new TermQuery();
termQuery.setFieldName("items.keyword");
termQuery.setTerm(ColumnValue.fromString("tablestore"));
ExistsQuery existsQuery = new ExistsQuery();
existsQuery.setFieldName("items.number");
BoolQuery childQuery = new BoolQuery();
childQuery.setMustQueries(Arrays.asList(termQuery, existsQuery));
NestedQuery nestedQuery = new NestedQuery();
nestedQuery.setPath("items");
nestedQuery.setQuery(childQuery);
nestedQuery.setScoreMode(ScoreMode.None);
SearchQuery searchQuery = new SearchQuery();
searchQuery.setQuery(nestedQuery);
異なる子行が複数の条件を個別に満たすことを許可する場合
条件ごとに 1 つの NestedQuery を作成し、外部の BoolQuery でネストされたクエリを組み合わせます。次の例では、items.keyword の値 tablestore と items.number の存在が、異なる子行によって一致することが許可されます。
TermQuery termQuery = new TermQuery();
termQuery.setFieldName("items.keyword");
termQuery.setTerm(ColumnValue.fromString("tablestore"));
NestedQuery termNestedQuery = new NestedQuery();
termNestedQuery.setPath("items");
termNestedQuery.setQuery(termQuery);
termNestedQuery.setScoreMode(ScoreMode.None);
ExistsQuery existsQuery = new ExistsQuery();
existsQuery.setFieldName("items.number");
NestedQuery existsNestedQuery = new NestedQuery();
existsNestedQuery.setPath("items");
existsNestedQuery.setQuery(existsQuery);
existsNestedQuery.setScoreMode(ScoreMode.None);
BoolQuery boolQuery = new BoolQuery();
boolQuery.setMustQueries(
Arrays.asList(termNestedQuery, existsNestedQuery));
SearchQuery searchQuery = new SearchQuery();
searchQuery.setQuery(boolQuery);
一致した子行の返却とハイライト
InnerHits を使用して、一致した子行の数、ソート順、およびハイライト設定を構成します。次の例では、items.description フィールドに hangzhou を含む子行をクエリし、ハイライトされた結果を返します。
MatchQuery matchQuery = new MatchQuery();
matchQuery.setFieldName("items.description");
matchQuery.setText("hangzhou");
HighlightParameter parameter = new HighlightParameter();
parameter.setPreTag("");
parameter.setPostTag("");
Highlight highlight = new Highlight();
highlight.addFieldHighlightParam("items.description", parameter);
InnerHits innerHits = new InnerHits();
innerHits.setLimit(3);
innerHits.setSort(new Sort(Arrays.asList(
new ScoreSort(), new DocSort(SortOrder.ASC))));
innerHits.setHighlight(highlight);
NestedQuery nestedQuery = new NestedQuery();
nestedQuery.setPath("items");
nestedQuery.setQuery(matchQuery);
nestedQuery.setScoreMode(ScoreMode.None);
nestedQuery.setInnerHits(innerHits);
SearchQuery searchQuery = new SearchQuery();
searchQuery.setQuery(nestedQuery);
複数レベルのネストされたクエリでは、一致した子行を返却またはハイライトする必要がある各 NestedQuery レベルで innerHits を設定します。