PolarSearch完全相容OpenSearch的官方用戶端,您可以使用相應的用戶端與PolarSearch進行互動。這使得您能夠通過Java或Python等常用程式設計語言高效地管理索引、操作文檔(包括增、刪、改、查)以及執行複雜搜尋,從而將搜尋功能無縫整合到您的應用程式中。
準備工作
已建立含有PolarSearch節點的叢集並設定了節點的管理員帳號。
擷取串連地址:在叢集的資料庫節點地區,將滑鼠懸浮在搜尋節點,根據您的業務環境,擷取PolarSearch節點的私網或公網地址。
串連叢集
Java client
1. 選擇傳輸層並添加依賴
OpenSearch Java用戶端需要搭配一個傳輸層架構來處理HTTP請求。您可以根據專案需求選擇Apache HttpClient5或RestClient。
【推薦】Apache HttpClient5
Maven
在pom.xml檔案中添加以下依賴:<!-- OpenSearch Java Client核心庫 --> <dependency> <groupId>org.opensearch.client</groupId> <artifactId>opensearch-java</artifactId> <version>2.19.0</version> </dependency> <!-- Apache HttpClient5 傳輸層 --> <dependency> <groupId>org.apache.httpcomponents.client5</groupId> <artifactId>httpclient5</artifactId> <version>5.2.1</version> </dependency>Gradle
在build.gradle檔案中添加以下依賴:dependencies { // OpenSearch Java Client核心庫 implementation 'org.opensearch.client:opensearch-java:2.19.0' // Apache HttpClient5 傳輸層 implementation 'org.apache.httpcomponents.client5:httpclient5:5.2.1' }
RestClient
Maven
在pom.xml檔案中添加以下依賴:<!-- OpenSearch Java Client核心庫 --> <dependency> <groupId>org.opensearch.client</groupId> <artifactId>opensearch-java</artifactId> <version>2.19.0</version> </dependency> <!-- RestClient 傳輸層 --> <dependency> <groupId>org.opensearch.client</groupId> <artifactId>opensearch-rest-client</artifactId> <version>2.19.0</version> </dependency>Gradle
在build.gradle檔案中添加以下依賴:dependencies { // OpenSearch Java Client核心庫 implementation 'org.opensearch.client:opensearch-java:2.19.0' // RestClient 傳輸層 implementation 'org.opensearch.client:opensearch-rest-client:2.19.0' }
2. 設定資料類
建立一個測試資料類,以供後續測試PolarSearch功能使用。
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);
}
}3. 初始化用戶端
根據您選擇的傳輸層,使用PolarSearch的串連資訊初始化用戶端。在實際使用中,您可以根據以下代碼配置將PolarSearch的相關資訊設定為環境變數,或直接將其賦值為參數的預設值,以便於測試使用。
Apache HttpClient5
以下樣本展示了如何初始化一個用戶端,當前範例程式碼禁用了SSL。
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 as our local testing clusters use 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
以下樣本展示了如何初始化一個用戶端,當前範例程式碼禁用了SSL。
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 the certificate since our testing cluster just uses the default security configuration
.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);
}
}4. 執行基本操作
以下程式碼片段展示了如何執行常見的索引和文檔操作。
建立索引
String index = "sample-index";
CreateIndexRequest createIndexRequest = new CreateIndexRequest.Builder().index(index).build();
client.indices().create(createIndexRequest);寫入文檔
IndexData indexData = new IndexData("first_name", "Bruce");
IndexRequest<IndexData> indexRequest = new IndexRequest.Builder<IndexData>().index(index).id("1").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());
}刪除文檔
client.delete(b -> b.index(index).id("1"));刪除索引
DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest.Builder().index(index).build();
DeleteIndexResponse deleteIndexResponse = client.indices().delete(deleteIndexRequest);Java high-level REST client
建議您使用Java client,因為Java high-level REST client已在OpenSearch中被廢棄,未來版本將不再支援該用戶端。
1. 添加依賴
在pom.xml檔案中添加以下依賴:
<!-- OpenSearch Java high-level REST client核心庫 -->
<dependency>
<groupId>org.opensearch.client</groupId>
<artifactId>opensearch-rest-high-level-client</artifactId>
<version>2.19.0</version>
</dependency>2. 配置安全連線
在使用REST用戶端之前,需配置應用程式的信任庫(truststore),以串連到安全外掛程式(Security plugin)。
如果您使用的是由受信任的憑證授權單位(CA)簽發的認證,則無需額外配置。
如果您使用的是自我簽署憑證(例如在測試或示範環境中),則可以使用以下命令建立一個自訂信任庫,並將根CA認證加入其中。
建立信任庫並匯入認證:
使用Java的keytool工具,將根CA認證匯入到一個新的信任庫檔案(例如truststore.jks)中。keytool -importcert -file <path/to/your/root-ca.pem> -alias <certificate_alias> -keystore <path/to/your/truststore.jks>執行此命令時,系統會提示您為新的信任庫設定密碼。
在應用程式中指定信任庫:
在您的Java應用程式啟動時,通過設定系統屬性,告知JVM使用您剛剛建立的信任庫。// 在用戶端初始化代碼之前執行 System.setProperty("javax.net.ssl.trustStore", "/full_path/to/your/truststore.jks"); System.setProperty("javax.net.ssl.trustStorePassword", "password-for-truststore");
如果您在配置安全功能時遇到問題,可以參考OpenSearch官方的常見問題和TLS 故障排查文檔。
3. 初始化用戶端
在實際使用中,您可以根據以下代碼配置將PolarSearch的相關資訊設定為環境變數,或直接將其賦值為參數的預設值,以便於測試使用。
// 僅用於示範目的,請勿在生產代碼中寫入程式碼憑證。
// 設定用於基本認證的憑證
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY,
new UsernamePasswordCredentials("<polarsearch_username>", "<polarsearch_password>"));
// 構建 RestClient,並設定 HTTP 用戶端配置回調以應用憑證
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 執行個體
RestHighLevelClient client = new RestHighLevelClient(builder);4. 執行基本操作
以下程式碼片段展示了如何執行常見的索引和文檔操作。
建立索引
// 建立一個帶有自訂設定和映射的索引
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);寫入文檔
// 向索引中添加資料
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);搜尋文檔
GetRequest getRequest = new GetRequest("custom-index", "1");
GetResponse getResponse = client.get(getRequest, RequestOptions.DEFAULT);
System.out.println("Retrieved document: " + getResponse.getSourceAsString());刪除文檔
DeleteRequest deleteDocumentRequest = new DeleteRequest("custom-index", "1");
DeleteResponse deleteResponse = client.delete(deleteDocumentRequest, RequestOptions.DEFAULT);
System.out.println("Document deleted with result: " + deleteResponse.getResult());刪除索引
DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest("custom-index");
AcknowledgedResponse deleteIndexResponse = client.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT);
System.out.println("Index deletion acknowledged: " + deleteIndexResponse.isAcknowledged());Low-level Python client
建議您使用Low-level Python client,因為High-level Python client在OpenSearch 2.1.0版本後已被廢棄。
1.配置環境
根據實際業務需求,進入指定的專案目錄。此處以
/home/PolarSearchTestPython為例。mkdir /home/PolarSearchTestPython cd /home/PolarSearchTestPython在
/home/PolarSearchTestPython目錄中,建立虛擬環境(venv)隔離專案依賴,避免全域汙染。python3 -m venv myenv啟用虛擬環境
source myenv/bin/activate安裝所需的Python依賴庫。
pip3 install opensearch-py
2. 串連PolarSearch
在您的Python代碼中匯入OpenSearch類,並使用PolarSearch的串連資訊建立用戶端執行個體。在實際使用中,您可以根據以下代碼配置將PolarSearch的相關資訊設定為環境變數,或直接將其賦值為參數的預設值,以便於測試使用。
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,
)3. 操作樣本
以下程式碼片段展示了如何執行常見的索引和文檔操作。
建立索引
使用client.indices.create()方法建立一個新索引。
index_name = 'python-test-index'
index_body = {
'settings': {
'index': {
'number_of_shards': 4
}
}
}
response = client.indices.create(index=index_name, body=index_body)寫入文檔
使用client.index()方法向指定索引中添加一個文檔。
document = {
'title': 'Moneyball',
'director': 'Bennett Miller',
'year': '2011'
}
response = client.index(
index = 'python-test-index',
body = document,
id = '1',
refresh = True
)執行大量操作
使用client.bulk()方法可以一次性執行多個操作,操作之間用\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)搜尋文檔
使用client.search()方法根據查詢條件搜尋文檔。
q = 'miller'
query = {
'size': 5,
'query': {
'multi_match': {
'query': q,
'fields': ['title^2', 'director']
}
}
}
response = client.search(
body = query,
index = 'python-test-index'
)刪除文檔
使用client.delete()方法刪除指定ID的文檔。
response = client.delete(
index = 'python-test-index',
id = '1'
)刪除索引
使用client.indices.delete()方法刪除整個索引。
response = client.indices.delete(
index = 'python-test-index'
)完整範例程式碼
下面是一個完整的樣本,示範了從建立索引到最終刪除索引的全過程。
Java client
範例程式碼
運行方式
mvn clean package
mvn exec:java -Dexec.mainClass=samples.OpenSearchClientExampleJava high-level REST client
範例程式碼
Low-level Python client
依賴配置
pip3 install opensearch-py樣本程式
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)