- User Guide
- Using different transport options
static class IndexData {
private String firstName;
private String lastName;
public IndexData(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
@Override
public String toString() {
return String.format("IndexData{first name='%s', last name='%s'}", firstName, lastName);
}
}
There are multiple low level transports which OpenSearchClient
could be configured with.
OpenSearchTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper());
OpenSearchClient client = new OpenSearchClient(transport);
The JacksonJsonpMapper
class (2.x versions) only supports Java 7 objects by default. Java 8 modules to support JDK8 classes such as the Date and Time API (JSR-310), Optional
, and more can be used by including the additional datatype dependency and adding the module. For example, to include JSR-310 classes:
OpenSearchTransport transport = new RestClientTransport(restClient,
new JacksonJsonpMapper(new ObjectMapper().registerModule(new JavaTimeModule())));
OpenSearchClient client = new OpenSearchClient(transport);
Upcoming OpenSearch 3.0.0
release brings HTTP/2 support and as such, the RestClientTransport
would switch to HTTP/2 if available (for both HTTPS and/or HTTP protocols). The desired protocol could be forced using RestClientBuilder.HttpClientConfigCallback
.
final OpenSearchTransport transport = ApacheHttpClient5TransportBuilder
.builder(hosts)
.setMapper(new JacksonJsonpMapper())
.build();
OpenSearchClient client = new OpenSearchClient(transport);
Upcoming OpenSearch 3.0.0
release brings HTTP/2 support and as such, the ApacheHttpClient5Transport
would switch to HTTP/2 if available (for both HTTPS and/or HTTP protocols). The desired protocol could be forced using ApacheHttpClient5TransportBuilder.HttpClientConfigCallback
, for example:
final OpenSearchTransport transport = ApacheHttpClient5TransportBuilder
.builder(httpHost)
.setMapper(new JacksonJsonpMapper())
.setHttpClientConfigCallback(new ApacheHttpClient5TransportBuilder.HttpClientConfigCallback() {
@Override
public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
return httpClientBuilder.setVersionPolicy(HttpVersionPolicy.FORCE_HTTP_2);
}
})
.build();
OpenSearchClient client = new OpenSearchClient(transport);
String index = "sample-index";
CreateIndexRequest createIndexRequest = new CreateIndexRequest.Builder().index(index).build();
client.indices().create(createIndexRequest);
IndexData indexData = new IndexData("John", "Doe");
IndexRequest<IndexData> indexRequest = new IndexRequest.Builder<IndexData>().index(index).id("1").document(indexData).build();
client.index(indexRequest);
indexData = new IndexData("John", "Joe");
indexRequest = new IndexRequest.Builder<IndexData>().index(index).id("2").document(indexData).build();
client.index(indexRequest);
SearchResponse<IndexData> searchResponse = client.search(s -> s.index(index), IndexData.class);
for (int i = 0; i < searchResponse.hits().hits().size(); i++) {
System.out.println(searchResponse.hits().hits().get(i).source());
}
When the target class is not defined or if the response result is a semi-structured data not tied to an object definition, use a raw JSON data representation as the target class. For example, the below snippet uses ObjectNode
from jackson.
SearchResponse<ObjectNode> searchResponse = client.search(b -> b.index(index), ObjectNode.class);
for (int i = 0; i < searchResponse.hits().hits().size(); i++) {
System.out.println(searchResponse.hits().hits().get(i).source());
}
SearchRequest searchRequest = new SearchRequest.Builder().query(q -> q.match(m -> m.field("firstName")
.query(FieldValue.of("John"))))
.build();
SearchResponse<IndexData> searchResponse = client.search(searchRequest, IndexData.class);
for (int i = 0; i < searchResponse.hits().hits().size(); i++) {
System.out.println(searchResponse.hits().hits().get(i).source());
}
ArrayList<BulkOperation> ops = new ArrayList<>();
SimplePojo doc1 = new SimplePojo("Document 1", "The text of document 1");
ops.add(new BulkOperation.Builder().index(
IndexOperation.of(io -> io.index(TEST_INDEX).id("id1").document(doc1))
).build());
SimplePojo doc2 = new SimplePojo("Document 2", "The text of document 2");
ops.add(new BulkOperation.Builder().index(
IndexOperation.of(io -> io.index(TEST_INDEX).id("id2").document(doc2))
).build());
SimplePojo doc3 = getLongDoc("Long Document 3", 100000);
ops.add(new BulkOperation.Builder().index(
IndexOperation.of(io -> io.index(TEST_INDEX).id("id3").document(doc3))
).build());
BulkRequest.Builder bulkReq = new BulkRequest.Builder()
.index(index)
.operations(ops)
.refresh(Refresh.WaitFor);
BulkResponse bulkResponse = client.bulk(bulkReq.build());
SearchRequest searchRequest = new SearchRequest.Builder().query(q -> q.match(m -> m.field("firstName")
.query(FieldValue.of("John"))))
.aggregations("firstNames", new Aggregation.Builder().terms(t -> t.field("firstName.keyword"))
.build())
.build();
SearchResponse<IndexData> searchResponse = client.search(searchRequest, IndexData.class);
for (Map.Entry<String, Aggregate> entry : searchResponse.aggregations().entrySet()) {
System.out.println("Agg - " + entry.getKey());
entry.getValue().sterms().buckets().array().forEach(b -> System.out.printf("%s : %d%n", b.key(), b.docCount()));
}
The following sample code deletes a document whose ID is 1.
client.delete(d -> d.index(index).id("1"));
DeleteIndexRequest deleteIndexRequest = new DeleteRequest.Builder().index(index).build();
DeleteIndexResponse deleteIndexResponse = client.indices().delete(deleteIndexRequest);
Before creating a data stream, you need to create an index template which configures a set of indices as a data stream.
A data stream must have a timestamp field. If not specified, OpenSearch uses @timestamp
as the default timestamp field name.
The following sample code creates an index template for data stream with a custom timestamp field, and creates a data stream which matches the name pattern specified in the index template.
String dataStreamIndexTemplateName = "sample-data-stream-template";
String timestampFieldName = "my_timestamp_field";
String namePattern = "sample-data-stream-*";
String dataStreamName = "sample-data-stream-1";
// Create an index template which configures data stream
PutIndexTemplateRequest putIndexTemplateRequest = new PutIndexTemplateRequest.Builder()
.name(dataStreamIndexTemplateName)
.indexPatterns(namePattern)
.dataStream(new DataStream.Builder()
.timestampField(t -> t.name(timestampFieldName))
.build())
.build();
PutIndexTemplateResponse putIndexTemplateResponse = javaClient().indices().putIndexTemplate(putIndexTemplateRequest);
// Create a data stream
CreateDataStreamRequest createDataStreamRequest = new CreateDataStreamRequest.Builder().name(dataStreamName).build();
CreateDataStreamResponse createDataStreamResponse = javaClient().indices().createDataStream(createDataStreamRequest);
GetDataStreamRequest getDataStreamRequest = new GetDataStreamRequest.Builder().name(dataStreamName).build();
GetDataStreamResponse getDataStreamResponse = javaClient().indices().getDataStream(getDataStreamRequest);
DataStreamsStatsRequest dataStreamsStatsRequest = new DataStreamsStatsRequest.Builder().name(dataStreamName).build();
DataStreamsStatsResponse dataStreamsStatsResponse = javaClient().indices().dataStreamsStats(dataStreamsStatsRequest);
DeleteDataStreamRequest deleteDataStreamRequest = new DeleteDataStreamRequest.Builder().name(dataStreamName).build();
DeleteDataStreamResponse deleteDataStreamResponse = javaClient().indices().deleteDataStream(deleteDataStreamRequest);
Creates a PIT. The keep_alive query parameter is required; it specifies how long to keep a PIT.
CreatePitRequest createPitRequest = new CreatePitRequest.Builder()
.targetIndexes(Collections.singletonList(index))
.keepAlive(new Time.Builder().time("100m").build()).build();
CreatePitResponse createPitResponse = javaClient()
.createPit(createPitRequest);
Returns all PITs in the OpenSearch cluster.
ListAllPitResponse listAllPitResponse = javaClient().listAllPit();
Deletes one, several, or all PITs. PITs are automatically deleted when the keep_alive time period elapses. However, to deallocate resources, you can delete a PIT using the Delete PIT API. The Delete PIT API supports deleting a list of PITs by ID or deleting all PITs at once.
DeletePitRequest deletePitRequest = new DeletePitRequest.Builder()
.pitId(Collections.singletonList("pit_id")).build();
DeletePitResponse deletePitResponse = javaClient()
.deletePit(deletePitRequest);
The following sample code cat indices with required headers and sorted by creation date
IndicesRequest indicesRequest = new IndicesRequest.Builder()
.headers("index,health,status,pri,rep,doc.count,creation.date,creation.date.string").sort("creation.date").build();
IndicesResponse indicesResponse = javaClient().cat().indices(indicesRequest);
The following sample code cat aliases with name "test-alias" and sorted by index
AliasesRequest aliasesRequest = new AliasesRequest.Builder().name("test-alias").sort("index").build();
AliasesResponse aliasesResponse = javaClient().cat().aliases(aliasesRequest);
The following sample code cat nodes sorted by cpu
NodesResponse nodesResponse = javaClient().cat().nodes(r -> r.sort("cpu"));
Similarly to the CAT Segments API, the PIT Segments API provides low-level information about the disk utilization of a PIT by describing its Lucene segments.
SegmentsResponse pitSegmentsResponse = javaClient().cat()
.pitSegments(r -> r.headers("index,shard,id,segment,size"));
Requests to OpenSearch Service and OpenSearch Serverless must be signed using the AWS signing protocol. Use AwsSdk2Transport
to send signed requests.
SdkHttpClient httpClient = ApacheHttpClient.builder().build();
OpenSearchClient client = new OpenSearchClient(
new AwsSdk2Transport(
httpClient,
"search-...us-west-2.es.amazonaws.com", // OpenSearch endpoint, without https://
"es" // signing service name, use "aoss" for OpenSearch Serverless
Region.US_WEST_2, // signing service region
AwsSdk2TransportOptions.builder().build()
)
);
InfoResponse info = client.info();
System.out.println(info.version().distribution() + ": " + info.version().number());
httpClient.close();