本文介紹如何使用PHP、Python、Java和Go等語言訪問Elasticsearch執行個體,並為您提供範例程式碼和注意事項。
準備工作
建立Elasticsearch執行個體。 具體操作,請參見建立Elasticsearch執行個體。
安裝對應語言的Elasticsearch用戶端。
建議建立與Elasticsearch相同版本的用戶端,避免出現相容性問題。Elasticsearch與用戶端版本相容性的詳細資料,請參見Compatibility。
Elasticsearch GO用戶端:Elasticsearch Go Client。
說明使用Go語言串連Elasticsearch前,您需要先安裝Go編譯環境,詳細資料請參見The Go Programming Language。本文樣本使用Go 1.19.1版本。
Elasticsearch Java用戶端:Elasticsearch Java API Client。
說明Java用戶端類型包括:Transport Client、Low Level REST Client、High Level REST Client和Java API Client,各類型的程式碼範例,請參見概述。本文以6.7版本的High Level REST Client為例。
由於Java Transport Client通過TCP與Elasticsearch進行通訊,當用戶端與不同版本的Elasticsearch通訊時,會存在相容性問題,所以官方在高版本叢集中已棄用Transport Client。如果您已經建立了,使用Transport Client 5.5或5.6版本與5.5或5.6版本的Elasticsearch叢集建立串連時會提示NoNodeAvailableException的錯誤,推薦您使用Transport Client 5.3.3或Java Low Level REST Client訪問Elasticsearch叢集,以保障版本的相容性。
Elasticsearch PHP用戶端:Elasticsearch PHP Client。
說明Elasticsearch的PHP用戶端提供的預設串連池並不適合雲上環境。Elasticsearch提供了負載平衡的網域名稱服務 (DNS),因此PHP用戶端訪問程式必須使用SimpleConnectionPool作為串連池,否則在觸發Elasticsearch重啟操作時會出現訪問串連異常的問題。同時,PHP用戶端訪問程式必須具備訪問串連失敗重連的機制。因為在PHP用戶端訪問程式使用SimpleConnectionPool作為串連池後,不排除在觸發Elasticsearch重啟操作時還會出現訪問串連異常問題(例如,提示No enabled connection)。
Elasticsearch Python用戶端:Elasticsearch Python Client。
更多Elasticsearch用戶端:Elasticsearch Clients。
開啟Elasticsearch執行個體的自動建立索引功能。具體操作請參見配置YML參數。
配置Elasticsearch執行個體白名單,確保網路互連。
如果運行代碼的伺服器與Elasticsearch執行個體在同一Virtual Private Cloud(Virtual Private Cloud)中,可通過Elasticsearch執行個體的私網地址進行連通。連通前,需要確保VPC私網訪問白名單(預設為0.0.0.0/0)中已添加了伺服器的私網IP地址。
如果運行代碼的伺服器在公網環境下,可通過Elasticsearch的公網地址進行連通。開啟Elasticsearch的公網地址,並將伺服器的公網IP地址添加到Elasticsearch執行個體公網地址訪問白名單中。具體操作,請參見配置Elasticsearch執行個體公網或私網訪問白名單。
重要如果您使用的是WIFI、寬頻等網路,需要將公網出口的跳板機IP地址配置進去。
您也可以將白名單配置為0.0.0.0/0,允許所有IPv4地址訪問Elasticsearch。此配置會導致執行個體完全暴露在公網中,增加安全風險,配置前請確認您是否可以接受這個風險。
如果未配置白名單或白名單配置錯誤,系統會提示連線逾時
Timeout connecting
。如果您需要通過用戶端訪問Kibana節點,還需要配置Kibana的訪問白名單。詳細資料,請參見配置Kibana公網或私網訪問白名單。
範例程式碼
常見用戶端訪問Elasticsearch執行個體的程式碼範例。
//以Go 1.19.1版本為例。
package main
import (
"log"
"github.com/elastic/go-elasticsearch/v7"
)
func main() {
cfg := elasticsearch.Config {
Addresses: []string{
"<YourEsHost>",
},
Username: "<UserName>",
Password: "<YourPassword>",
}
es, err := elasticsearch.NewClient(cfg)
if err != nil {
log.Fatalf("Error creating the client: %s", err)
}
res, err := es.Info()
if err != nil {
log.Fatalf("Error getting response: %s", err)
}
defer res.Body.Close()
log.Println(res)
}
//以6.7版本的High Level REST Client為例。
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.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.client.*;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class RestClientTest67 {
private static final RequestOptions COMMON_OPTIONS;
static {
RequestOptions.Builder builder = RequestOptions.DEFAULT.toBuilder();
// 預設緩衝限制為100MB,此處修改為30MB。
builder.setHttpAsyncResponseConsumerFactory(
new HttpAsyncResponseConsumerFactory
.HeapBufferedResponseConsumerFactory(30 * 1024 * 1024));
COMMON_OPTIONS = builder.build();
}
public static void main(String[] args) {
// Elasticsearch叢集需要basic auth驗證。
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
//訪問使用者名稱和密碼為您建立Elasticsearch執行個體時設定的使用者名稱和密碼,也是Kibana控制台的登入使用者名稱和密碼。
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("<UserName>", "<YourPassword>"));
// 通過builder建立rest client,配置http client的HttpClientConfigCallback。
// 單擊所建立的Elasticsearch執行個體ID,在基本資料頁面擷取公網地址,即為ES叢集地址。
RestClientBuilder builder = RestClient.builder(new HttpHost("<YourEsHost>", 9200, "http"))
.setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
@Override
public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
}
});
// RestHighLevelClient執行個體通過REST low-level client builder進行構造。
RestHighLevelClient highClient = new RestHighLevelClient(builder);
try {
// 建立request。
Map<String, Object> jsonMap = new HashMap<>();
jsonMap.put("<YourEsField1>", "<YourEsFieldValue1>");
jsonMap.put("<YourEsField2>", "<YourEsFieldValue2>");
IndexRequest indexRequest = new IndexRequest("<YourEsIndex>", "<YourEsType>", "<YourEsId>").source(jsonMap);
// 同步執行,並使用自訂RequestOptions(COMMON_OPTIONS)。
IndexResponse indexResponse = highClient.index(indexRequest, COMMON_OPTIONS);
long version = indexResponse.getVersion();
System.out.println("Index document successfully! " + version);
highClient.close();
} catch (IOException ioException) {
// 異常處理。
}
}
}
<?php
require 'vendor/autoload.php';
use Elasticsearch\ClientBuilder;
$client = ClientBuilder::create()->setHosts([
[
'host' => '<YourEsHost>',
'port' => '9200',
'scheme' => 'http',
'user' => '<UserName>',
'pass' => '<YourPassword>'
]
])->setConnectionPool('\Elasticsearch\ConnectionPool\SimpleConnectionPool', [])
->setRetries(10)->build();
$indexParams = [
'index' => '<YourEsIndex>',
'type' => '<YourEsType>',
'id' => '<YourEsId>',
'body' => ['<YourEsField>' => '<YourEsFieldValue>'],
'client' => [
'timeout' => 10,
'connect_timeout' => 10
]
];
$indexResponse = $client->index($indexParams);
print_r($indexResponse);
$searchParams = [
'index' => '<YourEsIndex>',
'type' => '<YourEsType>',
'body' => [
'query' => [
'match' => [
'<YourEsField>' => '<YourEsFieldValue>'
]
]
],
'client' => [
'timeout' => 10,
'connect_timeout' => 10
]
];
$searchResponse = $client->search($searchParams);
print_r($searchResponse);
?>
from elasticsearch import Elasticsearch, RequestsHttpConnection
import certifi
es = Elasticsearch(
['<YourEsHost>'],
http_auth=('<UserName>', '<YourPassword>'),
port=9200,
use_ssl=False
)
res = es.index(index="<YourEsIndex>", doc_type="<YourEsType>", id=<YourEsId>, body={"<YourEsField1>": "<YourEsFieldValue1>", "<YourEsField2>": "<YourEsFieldValue2>"})
res = es.get(index="<YourEsIndex>", doc_type="<YourEsType>", id=<YourEsId>)
print(res['_source'])
以上程式碼範例只展示了HTTP串連方式,如果ES叢集開啟了HTTPS協議,程式碼範例中需要將use_ssl改為True,並加上verify_certs=True,其餘不變。即:
es = Elasticsearch(
['<YourEsHost>'],
http_auth=('<UserName>', '<YourPassword>'),
port=9200,
use_ssl=True,
verify_certs=True
)
使用代碼時,您需要將以下欄位替換為對應的值。
參數 | 說明 |
<YourEsHost> | Elasticsearch執行個體的私網、公網地址。可在Elasticsearch執行個體的基本資料地區擷取。 |
<UserName> | 輸入Elasticsearch執行個體的使用者名稱 |
<YourPassword> | 輸入Elasticsearch執行個體的使用者密碼。 如果忘記密碼,可在Elasticsearch執行個體詳情頁的安全配置中重設。更多資訊,請參見重設Elasticsearch執行個體訪問密碼。 |
<YourEsIndex> | 索引名稱。 |
<YourEsType> | 文件類型。 重要 Elasticsearch 7.0以下版本可自訂文件類型,7.0及以上版本固定為 |
<YourEsId> | 文檔ID。 |
<YourEsField> | 欄位名稱。 |
<YourEsFieldValue> | <YourEsField>的值。 |