PolarSearch is fully compatible with official OpenSearch clients. Use these clients to manage indexes, perform document operations (create, delete, update, and query), and run complex searches from Java or Python applications.
Prerequisites
Before you begin, make sure you have:
A PolarDB cluster with a PolarSearch node and an administrator account set for the node
The PolarSearch endpoint: in the Database Nodes section of your cluster, hover over the Search Node to get the private or public endpoint
Connect to the cluster
Java client
The Java client is the recommended option. The Java high-level REST client is deprecated and will not be supported in future OpenSearch versions — see Java high-level REST client if you need to maintain an existing integration.
Step 1: Add dependencies
The Java client requires a transport-layer framework. Apache HttpClient 5 is recommended.
Apache HttpClient5 (Recommended)
Maven — add to pom.xml:
<!-- OpenSearch Java client core library -->
<dependency>
<groupId>org.opensearch.client</groupId>
<artifactId>opensearch-java</artifactId>
<version>2.19.0</version>
</dependency>
<!-- Apache HttpClient 5 transport layer -->
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
<version>5.2.1</version>
</dependency>Gradle — add to build.gradle:
dependencies {
// OpenSearch Java client core library
implementation 'org.opensearch.client:opensearch-java:2.19.0'
// Apache HttpClient 5 transport layer
implementation 'org.apache.httpcomponents.client5:httpclient5:5.2.1'
}RestClient
If you prefer RestClient over Apache HttpClient 5, replace the transport-layer dependency:
Maven:
<!-- RestClient transport layer -->
<dependency>
<groupId>org.opensearch.client</groupId>
<artifactId>opensearch-rest-client</artifactId>
<version>2.19.0</version>
</dependency>Gradle:
// RestClient transport layer
implementation 'org.opensearch.client:opensearch-rest-client:2.19.0'Step 2: Set up the data class
Create a data class to represent the documents you want to index.
static class IndexData {
private String title;
private String text;
public IndexData() {}
public IndexData(String title, String text) {
this.title = title;
this.text = text;
}
public String getTitle() { return title; }
public void setTitle(String title) { this.title = title; }
public String getText() { return text; }
public void setText(String text) { this.text = text; }
@Override
public String toString() {
return String.format("IndexData{title='%s', text='%s'}", title, text);
}
}Step 3: Initialize the client
Read the PolarSearch connection details from environment variables. For quick testing, you can also assign the values directly in code.
Replace the following placeholders with your actual values:
| Placeholder | Description |
|---|---|
<polarsearch_host> | PolarSearch endpoint (private or public) |
<polarsearch_port> | PolarSearch port |
<polarsearch_username> | Administrator account username |
<polarsearch_password> | Administrator account password |
Apache HttpClient5
Apache HttpClient 5 — this example disables SSL for local testing:
import org.apache.hc.client5.http.auth.AuthScope;
import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
import org.apache.hc.client5.http.impl.auth.BasicCredentialsProvider;
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBuilder;
import org.apache.hc.client5.http.ssl.ClientTlsStrategyBuilder;
import org.apache.hc.client5.http.ssl.NoopHostnameVerifier;
import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.ssl.SSLContextBuilder;
import org.opensearch.client.json.jackson.JacksonJsonpMapper;
import org.opensearch.client.opensearch.OpenSearchClient;
import org.opensearch.client.transport.httpclient5.ApacheHttpClient5TransportBuilder;
public class CreateClient {
public static void main(String[] args) throws Exception {
var env = System.getenv();
var hostname = env.getOrDefault("HOST", "<polarsearch_host>");
var port = Integer.parseInt(env.getOrDefault("PORT", "<polarsearch_port>"));
var user = env.getOrDefault("USERNAME", "<polarsearch_username>");
var pass = env.getOrDefault("PASSWORD", "<polarsearch_password>");
final var hosts = new HttpHost[] { new HttpHost("http", hostname, port) };
final var sslContext = SSLContextBuilder.create()
.loadTrustMaterial(null, (chains, authType) -> true)
.build();
final var transport = ApacheHttpClient5TransportBuilder.builder(hosts)
.setMapper(new JacksonJsonpMapper())
.setHttpClientConfigCallback(httpClientBuilder -> {
final var credentialsProvider = new BasicCredentialsProvider();
for (final var host : hosts) {
credentialsProvider.setCredentials(
new AuthScope(host),
new UsernamePasswordCredentials(user, pass.toCharArray())
);
}
// Disable SSL/TLS verification for local testing clusters with self-signed certificates
final var tlsStrategy = ClientTlsStrategyBuilder.create()
.setSslContext(sslContext)
.setHostnameVerifier(NoopHostnameVerifier.INSTANCE)
.build();
final var connectionManager = PoolingAsyncClientConnectionManagerBuilder.create()
.setTlsStrategy(tlsStrategy)
.build();
return httpClientBuilder
.setDefaultCredentialsProvider(credentialsProvider)
.setConnectionManager(connectionManager);
})
.build();
OpenSearchClient client = new OpenSearchClient(transport);
}
}RestClient
RestClient — this example disables SSL for local testing:
import org.apache.hc.client5.http.ssl.NoopHostnameVerifier;
import org.apache.hc.core5.ssl.SSLContextBuilder;
import org.opensearch.client.RestClient;
import org.opensearch.client.json.jackson.JacksonJsonpMapper;
import org.opensearch.client.opensearch.OpenSearchClient;
import org.opensearch.client.transport.rest_client.RestClientTransport;
public class CreateRestClient {
public static void main(String[] args) throws Exception {
var env = System.getenv();
var hostname = env.getOrDefault("HOST", "<polarsearch_host>");
var port = Integer.parseInt(env.getOrDefault("PORT", "<polarsearch_port>"));
var user = env.getOrDefault("USERNAME", "<polarsearch_username>");
var pass = env.getOrDefault("PASSWORD", "<polarsearch_password>");
final org.apache.http.HttpHost[] restHosts = new org.apache.http.HttpHost[] {
new org.apache.http.HttpHost(hostname, port, "http")
};
RestClient restClient = RestClient.builder(restHosts)
.setHttpClientConfigCallback(httpClientBuilder -> {
final org.apache.http.impl.client.BasicCredentialsProvider credentialsProvider =
new org.apache.http.impl.client.BasicCredentialsProvider();
for (final org.apache.http.HttpHost ignored : restHosts) {
credentialsProvider.setCredentials(
org.apache.http.auth.AuthScope.ANY,
new org.apache.http.auth.UsernamePasswordCredentials(user, pass)
);
}
try {
return httpClientBuilder
.setDefaultCredentialsProvider(credentialsProvider)
// Disable SSL for local testing
.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
.setSSLContext(SSLContextBuilder.create()
.loadTrustMaterial(null, (chains, authType) -> true)
.build());
} catch (Exception e) {
throw new RuntimeException(e);
}
}).build();
final RestClientTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper());
final OpenSearchClient client = new OpenSearchClient(transport);
}
}Step 4: Perform basic operations
The following snippets show common index and document operations.
Create an index
Create an index
String index = "sample-index";
CreateIndexRequest createIndexRequest = new CreateIndexRequest.Builder().index(index).build();
client.indices().create(createIndexRequest);Writing to a document
Index a document
IndexData indexData = new IndexData("first_name", "Bruce");
IndexRequest<IndexData> indexRequest = new IndexRequest.Builder<IndexData>()
.index(index).id("1").document(indexData).build();
client.index(indexRequest);Search for documents
Search for documents
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());
}Delete a document
Delete a document
client.delete(b -> b.index(index).id("1"));Delete an index
Delete an index
DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest.Builder().index(index).build();
DeleteIndexResponse deleteIndexResponse = client.indices().delete(deleteIndexRequest);Java high-level REST client
The Java high-level REST client is deprecated in OpenSearch and will not be supported in future versions. Use the Java client instead.
If you need to maintain an existing integration with the high-level REST client, follow the steps below.
Step 1: Add dependencies
Add to pom.xml:
<!-- OpenSearch Java high-level REST client core library -->
<dependency>
<groupId>org.opensearch.client</groupId>
<artifactId>opensearch-rest-high-level-client</artifactId>
<version>2.19.0</version>
</dependency>Step 2: Configure a secure connection
Before using the client, configure your application's truststore to connect to the Security plugin.
If you use a certificate issued by a trusted Certificate Authority (CA), no extra configuration is needed.
If you use a self-signed certificate (for example, in a test environment), import the root CA certificate into a truststore:
Create a truststore using the Java
keytoolutility:keytool -importcert -file <path/to/your/root-ca.pem> -alias <certificate_alias> -keystore <path/to/your/truststore.jks>When prompted, set a password for the new truststore.
Point the Java Virtual Machine (JVM) to the truststore by setting system properties before the client initialization code:
// Run before the client initialization code System.setProperty("javax.net.ssl.trustStore", "/full_path/to/your/truststore.jks"); System.setProperty("javax.net.ssl.trustStorePassword", "password-for-truststore");
If you have problems configuring security features, see the OpenSearch FAQ and TLS troubleshooting documentation.
Step 3: Initialize the client
// For demonstration purposes only. Do not hard-code credentials in production code.
// Set the credentials for basic authentication.
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY,
new UsernamePasswordCredentials("<polarsearch_username>", "<polarsearch_password>"));
// Build the RestClient and apply the credentials.
RestClientBuilder builder = RestClient.builder(
new HttpHost("<polarsearch_host>", <polarsearch_port>, "https"))
.setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
@Override
public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
}
});
// Create a RestHighLevelClient instance.
RestHighLevelClient client = new RestHighLevelClient(builder);Step 4: Perform basic operations
Create an index
Create an index
// Create an index with custom settings and mappings
CreateIndexRequest createIndexRequest = new CreateIndexRequest("custom-index");
createIndexRequest.settings(Settings.builder()
.put("index.number_of_shards", 4)
.put("index.number_of_replicas", 3)
);
HashMap<String, String> typeMapping = new HashMap<String, String>();
typeMapping.put("type", "integer");
HashMap<String, Object> ageMapping = new HashMap<String, Object>();
ageMapping.put("age", typeMapping);
HashMap<String, Object> mapping = new HashMap<String, Object>();
mapping.put("properties", ageMapping);
createIndexRequest.mapping(mapping);
CreateIndexResponse createIndexResponse = client.indices().create(createIndexRequest, RequestOptions.DEFAULT);Writing to a document
Index a document
// Add data to the index
IndexRequest request = new IndexRequest("custom-index");
request.id("1");
HashMap<String, String> stringMapping = new HashMap<String, String>();
stringMapping.put("message:", "Testing Java REST client");
request.source(stringMapping);
IndexResponse indexResponse = client.index(request, RequestOptions.DEFAULT);Search for a document
Get a document
GetRequest getRequest = new GetRequest("custom-index", "1");
GetResponse getResponse = client.get(getRequest, RequestOptions.DEFAULT);
System.out.println("Retrieved document: " + getResponse.getSourceAsString());Delete a document
Delete a document
DeleteRequest deleteDocumentRequest = new DeleteRequest("custom-index", "1");
DeleteResponse deleteResponse = client.delete(deleteDocumentRequest, RequestOptions.DEFAULT);
System.out.println("Document deleted with result: " + deleteResponse.getResult());Delete an index
Delete an index
DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest("custom-index");
AcknowledgedResponse deleteIndexResponse = client.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT);
System.out.println("Index deletion acknowledged: " + deleteIndexResponse.isAcknowledged());Dependency configuration (pom.xml)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>RESTClientSample</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- OpenSearch Java high-level REST client core library -->
<dependency>
<groupId>org.opensearch.client</groupId>
<artifactId>opensearch-rest-high-level-client</artifactId>
<version>2.19.0</version>
</dependency>
</dependencies>
</project>Example program (RESTClientSample.java)
package com.example;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
import org.opensearch.action.admin.indices.delete.DeleteIndexRequest;
import org.opensearch.action.delete.DeleteRequest;
import org.opensearch.action.delete.DeleteResponse;
import org.opensearch.action.get.GetRequest;
import org.opensearch.action.get.GetResponse;
import org.opensearch.action.index.IndexRequest;
import org.opensearch.action.index.IndexResponse;
import org.opensearch.action.support.master.AcknowledgedResponse;
import org.opensearch.client.RequestOptions;
import org.opensearch.client.RestClient;
import org.opensearch.client.RestClientBuilder;
import org.opensearch.client.RestHighLevelClient;
import org.opensearch.client.indices.CreateIndexRequest;
import org.opensearch.client.indices.CreateIndexResponse;
import org.opensearch.common.settings.Settings;
import java.io.IOException;
import java.util.HashMap;
public class RESTClientSample {
public static void main(String[] args) throws IOException {
// If you use a self-signed certificate, point to the keystore that contains the certificate.
// System.setProperty("javax.net.ssl.trustStore", "/full/path/to/keystore.jks");
// System.setProperty("javax.net.ssl.trustStorePassword", "password-to-keystore");
// Establish credentials for basic authentication.
// For demonstration purposes only. Do not hard-code credentials in production code.
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY,
new UsernamePasswordCredentials("<polarsearch_username>", "<polarsearch_password>"));
// Create the client
RestClientBuilder builder = RestClient.builder(
new HttpHost("<polarsearch_host>", <polarsearch_port>, "https"))
.setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
@Override
public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
}
});
RestHighLevelClient client = new RestHighLevelClient(builder);
// 1. Create an index with custom settings and mappings
CreateIndexRequest createIndexRequest = new CreateIndexRequest("custom-index");
createIndexRequest.settings(Settings.builder()
.put("index.number_of_shards", 4)
.put("index.number_of_replicas", 3)
);
HashMap<String, String> typeMapping = new HashMap<>();
typeMapping.put("type", "integer");
HashMap<String, Object> ageMapping = new HashMap<>();
ageMapping.put("age", typeMapping);
HashMap<String, Object> mapping = new HashMap<>();
mapping.put("properties", ageMapping);
createIndexRequest.mapping(mapping);
CreateIndexResponse createIndexResponse = client.indices().create(createIndexRequest, RequestOptions.DEFAULT);
System.out.println("Index creation acknowledged: " + createIndexResponse.isAcknowledged());
// 2. Add data to the index
IndexRequest request = new IndexRequest("custom-index");
request.id("1");
HashMap<String, String> stringMapping = new HashMap<>();
stringMapping.put("message", "Testing Java REST client");
request.source(stringMapping);
IndexResponse indexResponse = client.index(request, RequestOptions.DEFAULT);
System.out.println("Document indexed with result: " + indexResponse.getResult());
// 3. Get the document
GetRequest getRequest = new GetRequest("custom-index", "1");
GetResponse getResponse = client.get(getRequest, RequestOptions.DEFAULT);
System.out.println("Retrieved document: " + getResponse.getSourceAsString());
// 4. Delete the document
DeleteRequest deleteDocumentRequest = new DeleteRequest("custom-index", "1");
DeleteResponse deleteResponse = client.delete(deleteDocumentRequest, RequestOptions.DEFAULT);
System.out.println("Document deleted with result: " + deleteResponse.getResult());
// 5. Delete the index
DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest("custom-index");
AcknowledgedResponse deleteIndexResponse = client.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT);
System.out.println("Index deletion acknowledged: " + deleteIndexResponse.isAcknowledged());
client.close();
}
}Low-level Python client
Use the low-level Python client (opensearch-py). The high-level Python client has been deprecated since OpenSearch version 2.1.0.
Step 1: Set up the environment
Create and navigate to a project directory:
mkdir /home/PolarSearchTestPython cd /home/PolarSearchTestPythonCreate a virtual environment to isolate project dependencies:
python3 -m venv myenvActivate the virtual environment:
source myenv/bin/activateInstall the required library:
pip3 install opensearch-py
Step 2: Connect to PolarSearch
Import the OpenSearch class and create a client instance with your connection details. Read the details from environment variables, or assign them directly for testing.
from opensearchpy import OpenSearch
host = os.getenv("HOST", default="<polarsearch_host>")
port = int(os.getenv("PORT", <polarsearch_port>))
auth = (os.getenv("USERNAME", "<polarsearch_username>"), os.getenv("PASSWORD", "<polarsearch_password>"))
client = OpenSearch(
hosts=[{"host": host, "port": port}],
http_auth=auth,
use_ssl=False,
verify_certs=False,
ssl_show_warn=False,
)Step 3: Perform basic operations
Create an index
Create an index
Use client.indices.create() to create a new index.
index_name = 'python-test-index'
index_body = {
'settings': {
'index': {
'number_of_shards': 4
}
}
}
response = client.indices.create(index=index_name, body=index_body)Writing to a document
Index a document
Use client.index() to add a document to an index.
document = {
'title': 'Moneyball',
'director': 'Bennett Miller',
'year': '2011'
}
response = client.index(
index='python-test-index',
body=document,
id='1',
refresh=True
)Perform batch operations
Perform bulk operations
Use client.bulk() to execute multiple operations at once. Separate operations with \n.
movies = '{ "index" : { "_index" : "my-dsl-index", "_id" : "2" } } \n { "title" : "Interstellar", "director" : "Christopher Nolan", "year" : "2014"} \n { "create" : { "_index" : "my-dsl-index", "_id" : "3" } } \n { "title" : "Star Trek Beyond", "director" : "Justin Lin", "year" : "2015"} \n { "update" : {"_id" : "3", "_index" : "my-dsl-index" } } \n { "doc" : {"year" : "2016"} }'
client.bulk(body=movies)Search for documents
Search for documents
Use client.search() to search by query criteria.
q = 'miller'
query = {
'size': 5,
'query': {
'multi_match': {
'query': q,
'fields': ['title^2', 'director']
}
}
}
response = client.search(
body=query,
index='python-test-index'
)Delete a document
Delete a document
Use client.delete() to delete a document by ID.
response = client.delete(
index='python-test-index',
id='1'
)Delete an index
Delete an index
Use client.indices.delete() to delete an entire index.
response = client.indices.delete(
index='python-test-index'
)Complete example
Install the dependency
pip3 install opensearch-pyExample program
import os
from opensearchpy import OpenSearch
host = os.getenv("HOST", default="<polarsearch_host>")
port = int(os.getenv("PORT", <polarsearch_port>))
auth = (os.getenv("USERNAME", "<polarsearch_username>"), os.getenv("PASSWORD", "<polarsearch_password>"))
client = OpenSearch(
hosts=[{"host": host, "port": port}],
http_auth=auth,
use_ssl=False,
verify_certs=False,
ssl_show_warn=False,
)
# Create an index with non-default settings.
index_name = 'python-test-index'
index_body = {
'settings': {
'index': {
'number_of_shards': 4
}
}
}
response = client.indices.create(index=index_name, body=index_body)
print('\nCreating index:')
print(response)
# Add a document to the index.
document = {
'title': 'Moneyball',
'director': 'Bennett Miller',
'year': '2011'
}
id = '1'
response = client.index(
index=index_name,
body=document,
id=id,
refresh=True
)
print('\nAdding document:')
print(response)
# Perform bulk operations.
movies = '{ "index" : { "_index" : "my-dsl-index", "_id" : "2" } } \n { "title" : "Interstellar", "director" : "Christopher Nolan", "year" : "2014"} \n { "create" : { "_index" : "my-dsl-index", "_id" : "3" } } \n { "title" : "Star Trek Beyond", "director" : "Justin Lin", "year" : "2015"} \n { "update" : {"_id" : "3", "_index" : "my-dsl-index" } } \n { "doc" : {"year" : "2016"} }'
client.bulk(body=movies)
# Search for the document.
q = 'miller'
query = {
'size': 5,
'query': {
'multi_match': {
'query': q,
'fields': ['title^2', 'director']
}
}
}
response = client.search(
body=query,
index=index_name
)
print('\nSearch results:')
print(response)
# Delete the document.
response = client.delete(
index=index_name,
id=id
)
print('\nDeleting document:')
print(response)
# Delete the index.
response = client.indices.delete(
index=index_name
)
print('\nDeleting index:')
print(response)