A nested query with the Tablestore SDK for Java matches data in a Nested field while preserving child-row boundaries and can return the matching child rows.
Prerequisites
Install the Tablestore SDK for Java and initialize a client.
Feature description
A nested query queries child rows in a Nested field. Each child row in a Nested field independently preserves the relationships between its fields. You cannot directly query the subfields of a Nested field. Instead, wrap the subquery in a NestedQuery object.
NestedQuery.path specifies the path of the nested field to query. Field names in the subquery must use full paths. The subquery can be any Query type. To query a multi-level nested field, set path directly to the full path of the target nested field or nest NestedQuery objects to query each level.
Whether multiple conditions must be met by the same child row depends on how NestedQuery and BoolQuery are combined:
To require the same child row to meet multiple conditions, set a
BoolQuerythat contains the child conditions as the subquery of oneNestedQuery.To allow different child rows to meet the conditions separately, create one
NestedQueryfor each condition and combine the nested queries in an outerBoolQuery.
Call search to perform a nested query. In the query condition, specify the nested field path, subquery, and score mode.
SearchResponse search(SearchRequest request)
The following example queries child rows in the items nested field whose items.keyword field is equal to tablestore. The query returns up to 10 rows and the total number of matches.
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());
Parameters
Search request
request is a SearchRequest object that contains the following parameters.
|
Name |
Type |
Description |
|
tableName (required) |
String |
The name of the data table. |
|
indexName (required) |
String |
The name of the search index. |
|
searchQuery (required) |
SearchQuery |
The query condition and general query settings. |
|
columnsToGet (optional) |
SearchRequest.ColumnsToGet |
The columns to return. If this parameter is not configured, only primary key columns are returned. |
|
timeoutInMillisecond (optional) |
int |
The request-level query timeout in milliseconds. The default value is |
|
routingValues (optional) |
|
The primary key values that correspond to custom routing fields. Leave this parameter unset if custom routing is not configured. |
Query settings
request.searchQuery is a SearchQuery object that contains the following parameters.
|
Name |
Type |
Description |
|
query (required) |
Query |
The query condition. Set this parameter to a |
|
offset (optional) |
Integer |
The starting position of the query. |
|
limit (optional) |
Integer |
The maximum number of rows to return. Set this parameter to |
|
collapse (optional) |
Collapse |
The field collapse settings, which deduplicate results by a specified field. For configuration details, see Collapse query results. |
|
sort (optional) |
Sort |
The result sort order. For configuration details, see Sort and paginate results. |
|
trackTotalCount (optional) |
int |
The expected maximum number of matching rows to count. The default value is |
|
filter (optional) |
SearchFilter |
A filter that is applied to the results of |
|
aggregationList (optional) |
|
The aggregation settings. For configuration details, see Aggregation. |
|
groupByList (optional) |
|
The grouping settings. For configuration details, see Aggregation. |
|
token (optional) |
byte[] |
The pagination token. Set this parameter to the |
Nested query condition
request.searchQuery.query is a NestedQuery object that contains the following parameters.
|
Name |
Type |
Description |
|
path (required) |
String |
The path of the nested field to query. For a multi-level nested field, set this parameter to the full path of the target nested field, such as |
|
query (required) |
Query |
The query condition to execute on child rows under |
|
scoreMode (required) |
ScoreMode |
The parent-row scoring mode when multiple child rows match. |
|
innerHits (optional) |
InnerHits |
The settings for returning, sorting, paginating, and highlighting matching child rows. If you omit this parameter, details about matching child rows are not returned. |
|
weight (optional) |
float |
The query weight. The default value is |
Child-row return settings
request.searchQuery.query.innerHits is an InnerHits object that contains the following parameters.
|
Name |
Type |
Description |
|
sort (optional) |
Sort |
The sort order of matching child rows. You can use |
|
offset (optional) |
Integer |
The starting position from which to return matching child rows. |
|
limit (optional) |
Integer |
The maximum number of matching child rows to return. The default value is |
|
highlight (optional) |
Highlight |
The highlight settings for matching child rows. For information about fields and parameters that support highlighting, see Summary and highlighting. |
Returned columns
request.columnsToGet is a SearchRequest.ColumnsToGet object that contains the following parameters.
|
Name |
Type |
Description |
|
columns (optional) |
|
The attribute columns to return. Set this parameter only if |
|
returnAll (optional) |
boolean |
Specifies whether to return all attribute columns from the data table. The default value is |
|
returnAllFromIndex (optional) |
boolean |
Specifies whether to return all indexed attribute columns. The default value is |
Return values
Search response
search returns a SearchResponse object. The following table describes the core fields.
|
Name |
Type |
Description |
|
totalCount |
long |
The number of matching rows. Call |
|
rows |
|
The rows returned by this query. Call |
|
searchHits |
|
The query hits. Call |
|
nextToken |
byte[] |
The next-page token. Call |
|
isAllSuccess |
boolean |
Indicates whether all index partitions were queried successfully. Call |
Search hit
response.searchHits[] is a SearchHit object that contains the following core fields.
|
Name |
Type |
Description |
|
row |
Row |
The matching row or child row. Call |
|
score |
Double |
The relevance score. Call |
|
offset |
Integer |
The position of a nested child row in the original array. Call |
|
highlightResultItem |
HighlightResultItem |
The highlight result. Call |
|
searchInnerHits |
|
The matching child rows grouped by nested field path. Call |
Nested hit
response.searchHits[].searchInnerHits contains SearchInnerHit values with the following fields.
|
Name |
Type |
Description |
|
path |
String |
The nested field path. Call |
|
subSearchHits |
|
The matching child rows. Call |
Scenario examples
Query a multi-level nested field
To query a multi-level nested field, set path to the full path of the target nested field and specify the full subfield path in the subquery. The following example queries rows in which items.details.name is equal to 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);
Require the same child row to meet multiple conditions
Set a BoolQuery that contains multiple child conditions as the subquery of one NestedQuery. The following example requires the same child row in items to have an items.keyword value of tablestore and an items.number field.
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);
Allow different child rows to meet multiple conditions
Create one NestedQuery for each condition and combine the nested queries in an outer BoolQuery. The following example allows the items.keyword value of tablestore and the existence of items.number to be matched by different child rows.
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);
Return and highlight matching child rows
Use InnerHits to configure the number, sort order, and highlight settings of matching child rows. The following example queries child rows whose items.description field contains hangzhou and returns highlighted results.
MatchQuery matchQuery = new MatchQuery();
matchQuery.setFieldName("items.description");
matchQuery.setText("hangzhou");
HighlightParameter parameter = new HighlightParameter();
parameter.setPreTag("<em>");
parameter.setPostTag("</em>");
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);
In a multi-level nested query, configure innerHits in each NestedQuery level from which matching child rows must be returned or highlighted.