This page shows how to implement search using OpenSearch SDK for Java V4.0.0. The examples cover client initialization, query construction (including distinct, aggregation, sort, rank, and summary clauses), and result handling.
Prerequisites
Before you begin, ensure that you have:
An OpenSearch application with at least one index configured
An Alibaba Cloud AccessKey pair — use a Resource Access Management (RAM) user's AccessKey pair, not your Alibaba Cloud account's AccessKey pair. For details, see Create a RAM user and Create an AccessKey pair
The
AliyunServiceRoleForOpenSearchrole granted by your Alibaba Cloud account. For details, see AliyunServiceRoleForOpenSearch and Access authorization rules
Never include your AccessKey pair directly in source code. Store credentials in environment variables to prevent accidental exposure.
Set environment variables
Set the following environment variables with your RAM user's AccessKey ID and AccessKey secret.
Linux and macOS
export ALIBABA_CLOUD_ACCESS_KEY_ID=<access_key_id>
export ALIBABA_CLOUD_ACCESS_KEY_SECRET=<access_key_secret>Replace <access_key_id> and <access_key_secret> with your actual values.
Windows
Create an environment variable file and add the
ALIBABA_CLOUD_ACCESS_KEY_IDandALIBABA_CLOUD_ACCESS_KEY_SECRETvariables with your AccessKey ID and AccessKey secret as values.Restart Windows for the variables to take effect.
How it works
The SDK uses a three-layer client structure:
OpenSearch— holds your credentials and endpoint.OpenSearchClient— wrapsOpenSearchand handles HTTP communication.SearcherClient— built on top ofOpenSearchClient; use this to submit search requests.
All search parameters (query, distinct, aggregation, sort, rank, summary) are assembled into a SearchParams object, then run via SearcherClient.
Determine whether a request has failed by checking the error code and message in the response, not the HTTP status. For a full list of error codes, see Error codes.
Initialize the client
Read credentials from environment variables, then initialize the three-layer client. Replace <your-endpoint> with the OpenSearch API endpoint for your region.
package com.aliyun.opensearch;
import com.aliyun.opensearch.sdk.generated.OpenSearch;
public class SearchDemo {
private static final String APP_NAME = "<your-application-name>";
private static final String HOST = "<your-endpoint>";
public static void main(String[] args) {
// Read credentials from environment variables
String accessKey = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
String secret = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
// Build the three-layer client
OpenSearch openSearch = new OpenSearch(accessKey, secret, HOST);
OpenSearchClient serviceClient = new OpenSearchClient(openSearch);
SearcherClient searcherClient = new SearcherClient(serviceClient);
}
}Configure the config clause
The Config object sets paging, result format, and the fields to return.
import com.aliyun.opensearch.sdk.dependencies.com.google.common.collect.Lists;
import com.aliyun.opensearch.sdk.generated.search.Config;
import com.aliyun.opensearch.sdk.generated.search.SearchFormat;
// Attach the application and set paging
Config config = new Config(Lists.newArrayList(APP_NAME));
config.setStart(0); // starting offset
config.setHits(5); // results per page
// Result format: XML, JSON, or FULLJSON
config.setSearchFormat(SearchFormat.FULLJSON);
// Fields to include in the response
config.setFetchFields(Lists.newArrayList(
"id", "name", "phone", "int_arr", "literal_arr", "float_arr", "cate_id"
));
// Note: To ensure accurate total and viewtotal counts when reserved=false in the distinct clause,
// add the duniqfield parameter via the kvpairs clause:
// config.setKvpairs("duniqfield:cate_id");Set the search query and filter
Build a SearchParams object from the config, then set the query and filter.
import com.aliyun.opensearch.sdk.generated.search.SearchParams;
import com.aliyun.opensearch.search.SearchParamsBuilder;
SearchParams searchParams = new SearchParams(config);
SearchParamsBuilder paramsBuilder = SearchParamsBuilder.create(searchParams);
// Query against the "name" index field
searchParams.setQuery("name:'opensearch'");
// Raw query — must match the search query above
searchParams.setRawQuery("opensearch");
// Add a filter condition (AND logic)
paramsBuilder.addFilter("id>=0", "AND");Configure the distinct clause
Use Distinct to deduplicate results by a specified field.
import com.aliyun.opensearch.sdk.generated.search.Distinct;
Distinct dist = new Distinct();
dist.setKey("cate_id"); // field to deduplicate on
dist.setDistCount(1); // documents extracted per group
dist.setDistTimes(1); // number of extraction rounds
dist.setReserved(false); // discard documents after extraction
dist.setUpdateTotalHit(false); // do not subtract discarded docs from totalHits
dist.setDistFilter("cate_id<=3"); // apply deduplication only to matching documents
dist.setGrade("1.2"); // deduplication threshold
searchParams.addToDistincts(dist);Configure the aggregation clause
Use Aggregate to group and count results by a field. Multiple aggregations are supported.
import com.aliyun.opensearch.sdk.generated.search.Aggregate;
import java.util.HashSet;
import java.util.Set;
// Aggregation on a single field (detailed example)
Aggregate agg = new Aggregate();
agg.setGroupKey("cate_id"); // field to group by
agg.setAggFun("count()"); // aggregation function
agg.setAggFilter("cate_id=1"); // pre-aggregation filter
agg.setRange("0~10"); // aggregation range
agg.setAggSamplerThresHold("5"); // sampling threshold
agg.setAggSamplerStep("5"); // sampling step
agg.setMaxGroup("5"); // maximum groups returned
// Aggregation on multiple fields — use a Set<Aggregate>
Set<Aggregate> aggregates = new HashSet<>();
Aggregate agg1 = new Aggregate();
agg1.setGroupKey("cate_id");
agg1.setAggFun("count()");
aggregates.add(agg1);
Aggregate agg2 = new Aggregate();
agg2.setGroupKey("cate_id_1");
agg2.setAggFun("count()");
aggregates.add(agg2);
searchParams.setAggregates(aggregates);Configure sort and rank
Sort results by one or more fields, then specify rough-sort and fine-sort expressions.
import com.aliyun.opensearch.sdk.generated.search.Sort;
import com.aliyun.opensearch.sdk.generated.search.SortField;
import com.aliyun.opensearch.sdk.generated.search.Order;
import com.aliyun.opensearch.sdk.generated.search.Rank;
// Sort: descending by id, then ascending by RANK for ties
Sort sorter = new Sort();
sorter.addToSortFields(new SortField("id", Order.DECREASE));
sorter.addToSortFields(new SortField("RANK", Order.INCREASE));
searchParams.setSort(sorter);
// Rank: specify rough-sort and fine-sort expressions
Rank rank = new Rank();
rank.setFirstRankName("default"); // rough-sort expression
rank.setSecondRankName("default"); // fine-sort expression
rank.setReRankSize(5); // number of candidates for fine sort
searchParams.setRank(rank);Configure the summary clause
Add a summary (highlight snippet) to text fields in the response. The name field must be of the TEXT type for analysis to work.
// Configure via SearchParamsBuilder (recommended)
paramsBuilder.addSummary(
"name", // field name (must be TEXT type)
50, // segment length in characters
"em", // HTML tag used to highlight matched terms
"...", // connector between segments
1 // number of segments
);Configure a custom parameter
Pass additional parameters using a map, such as the biz parameter.
import java.util.HashMap;
import java.util.Map;
Map hashMap = new HashMap();
hashMap.put("biz", "type:web");
searchParams.setCustomParam(hashMap);Configure the re-search feature
Use the re-search feature to automatically rerun a query when the initial result count falls below a threshold.
// strategy:threshold,params:total_hits#10 — if total_hits on the first run is less than 10,
// the query is automatically rerun.
// Map<String, String> reSearchParams = new HashMap<String, String>();
// reSearchParams.put("re_search", "strategy:threshold,params:total_hits#10");
// Specify the from_request_id of the associated query.
// reSearchParams.put("from_request_id", "159851481919726888064081");
// searchParams.setCustomParam(reSearchParams);
// To disable the re-search feature:
// searchParams.putToCustomParam("disable", "re_search");Execute the query and handle results
Submit the query and parse the JSON response. Check the error code and message if a request fails — do not rely on HTTP status alone.
import com.aliyun.opensearch.sdk.dependencies.org.json.JSONObject;
import com.aliyun.opensearch.sdk.generated.commons.OpenSearchClientException;
import com.aliyun.opensearch.sdk.generated.commons.OpenSearchException;
import com.aliyun.opensearch.search.SearchResultDebug;
import com.aliyun.opensearch.sdk.generated.search.general.SearchResult;
try {
// Run the query
SearchResult searchResult = searcherClient.execute(paramsBuilder);
String result = searchResult.getResult();
// Parse and print the response
JSONObject obj = new JSONObject(result);
System.out.println(obj.toString());
// Print the request URL for debugging
SearchResultDebug debugResult = searcherClient.executeDebug(searchParams);
System.out.println(debugResult.getRequestUrl());
} catch (OpenSearchException e) {
e.printStackTrace();
} catch (OpenSearchClientException e) {
e.printStackTrace();
}