全部產品
Search
文件中心

Elasticsearch:通過用戶端訪問Elasticsearch

更新時間:Jun 30, 2024

本文介紹如何使用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執行個體的使用者名稱elastic

<YourPassword>

輸入Elasticsearch執行個體的使用者密碼。

如果忘記密碼,可在Elasticsearch執行個體詳情頁的安全配置中重設。更多資訊,請參見重設Elasticsearch執行個體訪問密碼

<YourEsIndex>

索引名稱。

<YourEsType>

文件類型。

重要

Elasticsearch 7.0以下版本可自訂文件類型,7.0及以上版本固定為_doc

<YourEsId>

文檔ID。

<YourEsField>

欄位名稱。

<YourEsFieldValue>

<YourEsField>的值。