Link Search Menu Expand Document Documentation Menu

Java 客户端

OpenSearch Java 客户端允许您通过 Java 方法和数据结构与 OpenSearch 集群进行交互,而不是通过 HTTP 方法和原始 JSON。例如,您可以使用对象向集群提交请求,以创建索引、向文档添加数据或使用客户端的内置方法完成其他操作。有关客户端的完整 API 文档和更多示例,请参阅 javadoc

本入门指南演示了如何连接到 OpenSearch、索引文档和运行查询。有关客户端源代码,请参阅 opensearch-java 存储库

使用 Apache HttpClient 5 Transport 安装客户端

要开始使用 OpenSearch Java 客户端,您需要提供一个传输。默认的 ApacheHttpClient5TransportBuilder 传输随 Java 客户端一起提供。要将 OpenSearch Java 客户端与默认传输一起使用,请将其作为依赖项添加到您的 pom.xml 文件中

<dependency>
  <groupId>org.opensearch.client</groupId>
  <artifactId>opensearch-java</artifactId>
  <version>3.0.0</version>
</dependency>

<dependency>
  <groupId>org.apache.httpcomponents.client5</groupId>
  <artifactId>httpclient5</artifactId>
  <version>5.2.1</version>
</dependency>

如果您正在使用 Gradle,请将以下依赖项添加到您的项目中

dependencies {
  implementation 'org.opensearch.client:opensearch-java:3.0.0'
  implementation 'org.apache.httpcomponents.client5:httpclient5:5.2.1'
}

您现在可以启动您的 OpenSearch 集群了。

使用 RestClient Transport 安装客户端

或者,您可以使用基于 RestClient 的传输创建 Java 客户端。在这种情况下,请确保您的项目 pom.xml 文件中包含以下依赖项

<dependency>
  <groupId>org.opensearch.client</groupId>
  <artifactId>opensearch-rest-client</artifactId>
  <version>3.1.0</version>
</dependency>

<dependency>
  <groupId>org.opensearch.client</groupId>
  <artifactId>opensearch-java</artifactId>
  <version>2.6.0</version>
</dependency>

如果您正在使用 Gradle,请将以下依赖项添加到您的项目中”

dependencies {
  implementation 'org.opensearch.client:opensearch-rest-client:3.1.0'
  implementation 'org.opensearch.client:opensearch-java:2.6.0'
}

您现在可以启动您的 OpenSearch 集群了。

安全

在您的 Java 应用程序中使用 REST 客户端之前,您必须配置应用程序的信任库以连接到安全插件。如果您正在使用自签名证书或演示配置,可以使用以下命令创建自定义信任库并添加根证书。

如果您使用的是来自受信任证书颁发机构 (CA) 的证书,则无需配置信任库。

keytool -import <path-to-cert> -alias <alias-to-call-cert> -keystore <truststore-name>

您现在可以将您的 Java 客户端指向信任库,并设置可以访问安全集群的基本身份验证凭据(请参阅后续部分中的示例代码)。

如果您在配置安全时遇到问题,请参阅常见问题TLS 故障排除

示例数据

本节使用一个名为 IndexData 的类,这是一个简单的 Java 类,用于存储基本数据和方法。对于您自己的 OpenSearch 集群,您可能会发现需要一个更强大的类来存储数据。

IndexData 类

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);
  }
}

使用 Apache HttpClient 5 Transport 初始化启用 SSL 和 TLS 的客户端

此代码示例使用了 OpenSearch 默认配置附带的基本凭据。如果您将 Java 客户端与您自己的 OpenSearch 集群一起使用,请务必更改代码,使其使用您自己的凭据。

以下示例代码初始化一个启用 SSL 和 TLS 的客户端

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;

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.PoolingAsyncClientConnectionManager;
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBuilder;
import org.apache.hc.client5.http.ssl.ClientTlsStrategyBuilder;
import org.apache.hc.core5.function.Factory;
import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
import org.apache.hc.core5.reactor.ssl.TlsDetails;
import org.apache.hc.core5.ssl.SSLContextBuilder;
import org.opensearch.client.opensearch.OpenSearchClient;
import org.opensearch.client.transport.OpenSearchTransport;
import org.opensearch.client.transport.httpclient5.ApacheHttpClient5TransportBuilder;

public class OpenSearchClientExample {
  public static void main(String[] args) throws Exception {
    System.setProperty("javax.net.ssl.trustStore", "/full/path/to/keystore");
    System.setProperty("javax.net.ssl.trustStorePassword", "password-to-keystore");

    final HttpHost host = new HttpHost("https", "localhost", 9200);
    final BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();
    // Only for demo purposes. Don't specify your credentials in code.
    credentialsProvider.setCredentials(new AuthScope(host), new UsernamePasswordCredentials("admin", "admin".toCharArray()));

    final SSLContext sslcontext = SSLContextBuilder
      .create()
      .loadTrustMaterial(null, (chains, authType) -> true)
      .build();

    final ApacheHttpClient5TransportBuilder builder = ApacheHttpClient5TransportBuilder.builder(host);
    builder.setHttpClientConfigCallback(httpClientBuilder -> {
      final TlsStrategy tlsStrategy = ClientTlsStrategyBuilder.create()
        .setSslContext(sslcontext)
        // See https://issues.apache.org/jira/browse/HTTPCLIENT-2219
        .setTlsDetailsFactory(new Factory<SSLEngine, TlsDetails>() {
          @Override
          public TlsDetails create(final SSLEngine sslEngine) {
            return new TlsDetails(sslEngine.getSession(), sslEngine.getApplicationProtocol());
          }
        })
        .build();

      final PoolingAsyncClientConnectionManager connectionManager = PoolingAsyncClientConnectionManagerBuilder
        .create()
        .setTlsStrategy(tlsStrategy)
        .build();

      return httpClientBuilder
        .setDefaultCredentialsProvider(credentialsProvider)
        .setConnectionManager(connectionManager);
    });

    final OpenSearchTransport transport = builder.build();
    OpenSearchClient client = new OpenSearchClient(transport);
  }
}

使用 RestClient Transport 初始化启用 SSL 和 TLS 的客户端

此代码示例使用了 OpenSearch 默认配置附带的基本凭据。如果您将 Java 客户端与您自己的 OpenSearch 集群一起使用,请务必更改代码,使其使用您自己的凭据。

以下示例代码初始化一个启用 SSL 和 TLS 的客户端

import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.opensearch.client.RestClient;
import org.opensearch.client.RestClientBuilder;
import org.opensearch.client.json.jackson.JacksonJsonpMapper;
import org.opensearch.client.opensearch.OpenSearchClient;
import org.opensearch.client.transport.OpenSearchTransport;
import org.opensearch.client.transport.rest_client.RestClientTransport;

public class OpenSearchClientExample {
  public static void main(String[] args) throws Exception {
    System.setProperty("javax.net.ssl.trustStore", "/full/path/to/keystore");
    System.setProperty("javax.net.ssl.trustStorePassword", "password-to-keystore");

    final HttpHost host = new HttpHost("https", "localhost", 9200);
    final BasicCredentialsProvider credentialsProvider = new BasicCredentialsProvider();
    //Only for demo purposes. Don't specify your credentials in code.
    credentialsProvider.setCredentials(new AuthScope(host), new UsernamePasswordCredentials("admin", "admin".toCharArray()));

    //Initialize the client with SSL and TLS enabled
    final RestClient restClient = RestClient.builder(host).
      setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
        @Override
        public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
        return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
        }
      }).build();

    final OpenSearchTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper());
    final OpenSearchClient client = new OpenSearchClient(transport);
  }
}

连接到 Amazon OpenSearch 服务

以下示例演示了连接到 Amazon OpenSearch 服务

SdkHttpClient httpClient = ApacheHttpClient.builder().build();

OpenSearchClient client = new OpenSearchClient(
    new AwsSdk2Transport(
        httpClient,
        "search-...us-west-2.es.amazonaws.com", // OpenSearch endpoint, without https://
        "es",
        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();

连接到 Amazon OpenSearch Serverless

以下示例演示了连接到 Amazon OpenSearch 无服务器服务

SdkHttpClient httpClient = ApacheHttpClient.builder().build();

OpenSearchClient client = new OpenSearchClient(
    new AwsSdk2Transport(
        httpClient,
        "search-...us-west-2.aoss.amazonaws.com", // OpenSearch endpoint, without https://
        "aoss"
        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();

创建索引

您可以使用以下代码创建具有非默认设置的索引

String index = "sample-index";
CreateIndexRequest createIndexRequest = new CreateIndexRequest.Builder().index(index).build();
client.indices().create(createIndexRequest);

IndexSettings indexSettings = new IndexSettings.Builder().autoExpandReplicas("0-all").build();
PutIndicesSettingsRequest putIndicesSettingsRequest = new PutIndicesSettingsRequest.Builder().index(index).value(indexSettings).build();
client.indices().putSettings(putIndicesSettingsRequest);

索引数据

您可以使用以下代码将数据索引到 OpenSearch 中

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());
}

删除文档

以下示例代码删除 ID 为 1 的文档

client.delete(b -> b.index(index).id("1"));

删除索引

以下示例代码删除索引

DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest.Builder().index(index).build();
DeleteIndexResponse deleteIndexResponse = client.indices().delete(deleteIndexRequest);

示例程序

以下示例程序创建一个客户端,添加一个具有非默认设置的索引,插入一个文档,搜索该文档,删除该文档,然后删除该索引

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.client.RestClient;
import org.opensearch.client.RestClientBuilder;
import org.opensearch.client.base.RestClientTransport;
import org.opensearch.client.base.Transport;
import org.opensearch.client.json.jackson.JacksonJsonpMapper;
import org.opensearch.client.opensearch.OpenSearchClient;
import org.opensearch.client.opensearch._global.IndexRequest;
import org.opensearch.client.opensearch._global.IndexResponse;
import org.opensearch.client.opensearch._global.SearchResponse;
import org.opensearch.client.opensearch.indices.*;
import org.opensearch.client.opensearch.indices.put_settings.IndexSettingsBody;

import java.io.IOException;

public class OpenSearchClientExample {
  public static void main(String[] args) {
    RestClient restClient = null;
    try{
      System.setProperty("javax.net.ssl.trustStore", "/full/path/to/keystore");
      System.setProperty("javax.net.ssl.trustStorePassword", "password-to-keystore");

      //Only for demo purposes. Don't specify your credentials in code.
      final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
      credentialsProvider.setCredentials(AuthScope.ANY,
        new UsernamePasswordCredentials("admin", "admin"));

      //Initialize the client with SSL and TLS enabled
      restClient = RestClient.builder(new HttpHost("localhost", 9200, "https")).
        setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
          @Override
          public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
          return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
          }
        }).build();
      Transport transport = new RestClientTransport(restClient, new JacksonJsonpMapper());
      OpenSearchClient client = new OpenSearchClient(transport);

      //Create the index
      String index = "sample-index";
      CreateIndexRequest createIndexRequest = new CreateIndexRequest.Builder().index(index).build();
      client.indices().create(createIndexRequest);

      //Add some settings to the index
      IndexSettings indexSettings = new IndexSettings.Builder().autoExpandReplicas("0-all").build();
      IndexSettingsBody settingsBody = new IndexSettingsBody.Builder().settings(indexSettings).build();
      PutSettingsRequest putSettingsRequest = new PutSettingsRequest.Builder().index(index).value(settingsBody).build();
      client.indices().putSettings(putSettingsRequest);

      //Index some data
      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 the document
      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 the document
      client.delete(b -> b.index(index).id("1"));

      // Delete the index
      DeleteIndexRequest deleteIndexRequest = new DeleteRequest.Builder().index(index).build();
      DeleteIndexResponse deleteIndexResponse = client.indices().delete(deleteIndexRequest);
    } catch (IOException e){
      System.out.println(e.toString());
    } finally {
      try {
        if (restClient != null) {
          restClient.close();
        }
      } catch (IOException e) {
        System.out.println(e.toString());
      }
    }
  }
}