You need to enable JavaScript to run this app.
文档中心
云搜索服务

云搜索服务

复制全文
下载 pdf
通过 Java 连接实例
通过 Java 连接 OpenSearch 实例
复制全文
下载 pdf
通过 Java 连接 OpenSearch 实例
本文介绍如何使用 Java 语言,通过 opensearch-java 客户端连接 OpenSearch 实例,并为您提供示例代码。​
准备工作​
  • 提前创建 OpenSearch 实例,并确保为正常运行状态。创建实例的具体操作,请参见创建实例。​
  • 您在连接实例前,请先在实例详情页面获取实例访问地址、实例访问用户。​
说明​
  • 对于需要使用证书连接的 HTTPS 协议实例,还需要下载证书并保存到本地路径。​
  • 如果遗忘实例访问用户(admin)的密码,可以选择重置密码。具体操作步骤,请参见重置访问密码。​
  • 如果需要使用实例公网地址访问,您可以为实例开启公网访问,然后绑定一个弹性公网 EIP。具体操作步骤,请参见配置实例公网访问。​
  • 运行 Java 代码的服务器需要提前安装 Java 环境,由于示例代码使用的 Apache HttpClient 版本为 5.2.1,需安装 8u252 或以上版本 JDK;以及安装 3.5 或以上版本 Maven。具体操作,请参见安装JDK和安装Maven。​
注意事项​
  • 支持 Java 8/11/17/21,如果 Java 版本不匹配请先进行版本升级。​
  • 确保运行 Java 代码的服务器与 OpenSearch 实例网络互通。​
  • 如果运行 Java 代码的服务器与实例在相同的私有网络 VPC 中,则可以通过实例的私网地址进行连接。​
  • 如果运行 Java 代码的服务器在公网环境下,则可以通过实例的公网地址进行连接。具体操作步骤,请参见配置实例公网访问。​
添加依赖​
Maven​
​
<dependency>​
<groupId>org.opensearch.client</groupId>​
<artifactId>opensearch-java</artifactId>​
<version>2.21.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:2.21.0'​
implementation 'org.apache.httpcomponents.client5:httpclient5:5.2.1'​
}​
​
连接实例​
运行以下程序,返回如下类似信息:​
​
current cluster status is: GREEN​
​
通过 HTTPS 证书连接实例​
该场景适用于连接访问方式为 HTTPS 的 OpenSearch 实例,且需要认证实例的 HTTPS 证书。​
示例代码如下:​
​
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.config.ConnectionConfig;​
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.apache.hc.core5.util.Timeout;​
import org.opensearch.client.opensearch.OpenSearchClient;​
import org.opensearch.client.opensearch.cat.HealthRequest;​
import org.opensearch.client.opensearch.cluster.HealthResponse;​
import org.opensearch.client.transport.OpenSearchTransport;​
import org.opensearch.client.transport.httpclient5.ApacheHttpClient5TransportBuilder;​
import java.io.InputStream;​
import java.nio.file.Files;​
import java.nio.file.Paths;​
import java.security.KeyStore;​
import java.security.cert.CertificateFactory;​
​
import java.util.Arrays;​
import java.util.Collections;​
import java.util.List;​
import java.util.concurrent.TimeUnit;​
​
​
public class OSinitClientWithCA {​
​
public OpenSearchClient initClientWithCA(List<HttpHost> hosts, String caPath, String user, String password) throws Exception {​
​
if (hosts == null || hosts.isEmpty()) {​
throw new IllegalArgumentException("invalid empty hosts");​
}​
BasicCredentialsProvider provider = new BasicCredentialsProvider();​
for (HttpHost host : hosts) {​
provider.setCredentials(new AuthScope(host), new UsernamePasswordCredentials(user, password.toCharArray()));​
}​
​
SSLContext sslContext;​
try {​
InputStream is = Files.newInputStream(Paths.get(caPath));​
KeyStore trustStore = KeyStore.getInstance("pkcs12");​
trustStore.load(null,null);​
trustStore.setCertificateEntry("ca", CertificateFactory.getInstance("X.509").generateCertificate(is));​
sslContext = new SSLContextBuilder().loadTrustMaterial(trustStore, null).build();​
} catch (Exception e) {​
// add your own log here​
throw e;​
}​
​
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)​
.setMaxConnTotal(1000)​
.setMaxConnPerRoute(1000)​
.setDefaultConnectionConfig(ConnectionConfig.custom()​
.setTimeToLive(300, TimeUnit.SECONDS)​
.setConnectTimeout(Timeout.ofSeconds(5))​
.setSocketTimeout(Timeout.ofSeconds(60))​
.build())​
.build();​
​
return httpClientBuilder​
.setDefaultCredentialsProvider(provider)​
.setConnectionManager(connectionManager);​
});​
​
final OpenSearchTransport transport = builder.build();​
return new OpenSearchClient(transport);​
}​
​
public static void main(String[] args) throws Exception {​
String file = "<证书保存地址>";​
OpenSearchClient client = new OSinitClientWithCA().initClientWithCA(​
Arrays.asList(new HttpHost("https","<访问域名>", 9200)),​
file, "admin", "<用户密码>");​
​
try {​
HealthResponse health = client.cluster().health();​
System.out.println("current cluster status is: " + health.status()); // 输出 - current cluster status is: GREEN​
} catch (Exception e) {​
e.printStackTrace();​
}​
client.shutdown();​
}​
​
}​
​
忽略 HTTPS 证书连接实例​
该场景适用于连接访问方式为 HTTPS 的 OpenSearch 实例,连接过程中忽略 HTTPS 证书。​
示例代码如下:​
​
import org.apache.hc.client5.http.auth.AuthScope;​
import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;​
import org.apache.hc.client5.http.config.ConnectionConfig;​
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.apache.hc.core5.util.Timeout;​
import org.opensearch.client.opensearch.OpenSearchClient;​
import org.opensearch.client.opensearch.cluster.HealthResponse;​
import org.opensearch.client.transport.OpenSearchTransport;​
import org.opensearch.client.transport.httpclient5.ApacheHttpClient5TransportBuilder;​
​
import javax.net.ssl.SSLContext;​
import javax.net.ssl.SSLEngine;​
import java.util.concurrent.TimeUnit;​
​
​
public class OSinitClientIgnoreCA {​
​
public OpenSearchClient initClientIgnoreCA(HttpHost[] hosts, String user, String password) throws Exception {​
​
if (hosts == null || hosts.length == 0) {​
throw new IllegalArgumentException("invalid empty hosts");​
}​
BasicCredentialsProvider provider = new BasicCredentialsProvider();​
for (HttpHost host : hosts) {​
provider.setCredentials(new AuthScope(host), new UsernamePasswordCredentials(user, password.toCharArray()));​
}​
​
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, (x509Certificates, s) -> true).build(); // 跳过 SSL 证书校验​
​
final ApacheHttpClient5TransportBuilder builder = ApacheHttpClient5TransportBuilder.builder(hosts);​
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)​
.setMaxConnTotal(1000) //最大连接数​
.setMaxConnPerRoute(1000) //route的最大连接数​
.setDefaultConnectionConfig(ConnectionConfig.custom()​
.setTimeToLive(300, TimeUnit.SECONDS) //链接最大存活时间,实例重启后自动平衡负载周期​
.setConnectTimeout(Timeout.ofSeconds(5)) //连接超时时间​
.setSocketTimeout(Timeout.ofSeconds(60))​
.build())​
.build();​
​
return httpClientBuilder​
.setDefaultCredentialsProvider(provider)​
.setConnectionManager(connectionManager);​
});​
​
final OpenSearchTransport transport = builder.build();​
return new OpenSearchClient(transport);​
}​
​
public static void main(String[] args) throws Exception {​
OpenSearchClient client = new OSinitClientIgnoreCA().initClientIgnoreCA(​
new HttpHost[]{new HttpHost("https","<访问域名>", 9200)},​
"admin", "<用户密码>");​
​
try {​
HealthResponse health = client.cluster().health();​
System.out.println("current cluster status is: " + health.status()); // 输出 - current cluster status is: GREEN​
} catch (Exception e) {​
e.printStackTrace();​
}​
client.shutdown();​
}​
​
}​
​
连接 HTTP 实例​
该场景适用于连接访问方式为 HTTP 的 OpenSearch 实例。​
示例代码如下:​
​
import org.apache.hc.client5.http.auth.AuthScope;​
import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;​
import org.apache.hc.client5.http.config.ConnectionConfig;​
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.apache.hc.core5.util.Timeout;​
import org.opensearch.client.opensearch.OpenSearchClient;​
import org.opensearch.client.opensearch.cluster.HealthResponse;​
import org.opensearch.client.transport.OpenSearchTransport;​
import org.opensearch.client.transport.httpclient5.ApacheHttpClient5TransportBuilder;​
​
import javax.net.ssl.SSLContext;​
import javax.net.ssl.SSLEngine;​
import java.util.concurrent.TimeUnit;​
​
​
public class OSinitClientHttp {​
​
public OpenSearchClient initClientHttp(HttpHost[] hosts, String user, String password) throws Exception {​
​
if (hosts == null || hosts.length == 0) {​
throw new IllegalArgumentException("invalid empty hosts");​
}​
BasicCredentialsProvider provider = new BasicCredentialsProvider();​
for (HttpHost host : hosts) {​
provider.setCredentials(new AuthScope(host), new UsernamePasswordCredentials(user, password.toCharArray()));​
}​
​
final ApacheHttpClient5TransportBuilder builder = ApacheHttpClient5TransportBuilder.builder(hosts);​
builder.setHttpClientConfigCallback(httpClientBuilder -> {​
final PoolingAsyncClientConnectionManager connectionManager = PoolingAsyncClientConnectionManagerBuilder​
.create()​
.setMaxConnTotal(1000) //最大连接数​
.setMaxConnPerRoute(1000) //route 的最大连接数​
.setDefaultConnectionConfig(ConnectionConfig.custom()​
.setTimeToLive(300, TimeUnit.SECONDS) //链接最大存活时间,实例重启后自动平衡负载周期​
.setConnectTimeout(Timeout.ofSeconds(5)) //连接超时时间​
.setSocketTimeout(Timeout.ofSeconds(60))​
.build())​
.build();​
return httpClientBuilder​
.setDefaultCredentialsProvider(provider)​
.setConnectionManager(connectionManager);​
});​
​
final OpenSearchTransport transport = builder.build();​
return new OpenSearchClient(transport);​
}​
​
public static void main(String[] args) throws Exception {​
OpenSearchClient client = new OSinitClientHttp().initClientHttp(​
new HttpHost[]{new HttpHost("http","<访问域名>", 9200)},​
"admin", "<用户密码>");​
​
try {​
HealthResponse health = client.cluster().health();​
System.out.println("current cluster status is: " + health.status()); //输出 - current cluster status is: GREEN​
} catch (Exception e) {​
e.printStackTrace();​
}​
client.shutdown();​
}​
​
}​
​
创建索引​
执行以下代码,可以向目标索引中写入文档。​
​
// 最小化创建索引​
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);​
​
​
// 创建disann 向量索引​
String index = "sample-index";​
final KnnVectorProperty nameVector = KnnVectorProperty.of(​
v -> v.dimension(4)​
.method(m -> m.spaceType("cosinesimil")​
.engine("diskann")​
.name("diskann")​
.parameters("L", JsonData.of(30))​
.parameters("R", JsonData.of(32))​
)​
);​
​
​
client.indices().create(ci -> ci.index(index)​
.mappings(​
builder -> builder.properties(​
"firstName", p -> p.text(t -> t.analyzer("ik_smart"))​
).properties("nameVector", p -> p.knnVector(nameVector))​
)​
.settings(s -> s.index(indexSetting -> indexSetting.knn(true))));​
​
// 更新索引配置​
client.indices().putSettings(ps -> ps.index(index)​
.settings(s -> s.autoExpandReplicas("0-all"))​
);​
​
增删改查​
这里只展示向量和文本基本的增删改查样例, 其他高级特性如利用 ingest pipeline 无感写入向量等,参考其他最佳实践文档。​
文档数据​
增删改查所有的文档结构基于以下类。​
​
class IndexData {​
private String firstName;​
private Float[] nameVector;​
public IndexData() {​
​
}​
public IndexData(String firstName, Float[] nameVector) {​
this.firstName = firstName;​
this.nameVector = nameVector;​
}​
​
public void setFirstName(String firstName) {​
this.firstName = firstName;​
}​
​
public void setNameVector(Float[] nameVector) {​
this.nameVector = nameVector;​
}​
​
public String getFirstName() {​
return this.firstName;​
}​
​
public Float[] getNameVector() {​
return this.nameVector;​
}​
}​
​
写入文档​
​
IndexData indexData = new IndexData( "云搜索", new Float[]{ 1.0f,1.0f,1.0f,1.0f});​
client.index(ib -> ib.index(index).id("1").document(indexData));​
client.indices().refresh(r -> r.index(index));​
​
搜索文档​
  • 文本搜索​
​
// 文本搜索​
SearchResponse<IndexData> search_res = client.search(​
r -> r.query(​
q -> q.match(​
match -> match.field("firstName")​
.query(f -> f.stringValue("云搜索"))​
.analyzer("ik_smart")​
)​
)​
, IndexData.class);​
​
System.out.println(search_res.hits().hits().get(0).source().getFirstName());​
​
  • 向量搜索​
​
// 向量搜索​
SearchResponse<IndexData> vector_res = client.search(​
r -> r.query(​
q -> q.knn(​
knn -> knn.field("nameVector")​
.k(10)​
.vector(new float[]{ 1.0f, 1.0f, 1.0f, 1.0f})​
)​
)​
, IndexData.class);​
System.out.println(vector_res.hits().hits().get(0).source().getFirstName());​
​
  • 使用原始的 JSON 搜索​
​
// 使用原始的 JSON 搜索​
String json_query = "{\"match\":{ \"firstName\": \"云搜索\"}}";​
String encodedJSON = Base64.getEncoder().encodeToString(json_query.getBytes());​
​
SearchResponse<IndexData> search_by_json = client.search(​
r -> r.query(​
q -> q.wrapper(m -> m.query(encodedJSON))),​
IndexData.class​
);​
System.out.println(search_by_json.hits().hits().get(0).source().getFirstName());​
​
//class 参数传递 com.fasterxml.jackson.databind.node.ObjectNode 可以获取原始 JSON​
​
  • 语义搜索及其他需要用到 pipeline 的场景​
  • 添加依赖。​
  • Maven​
  • ​
    <dependency>​
    <groupId>org.opensearch.client</groupId>​
    <artifactId>opensearch-rest-high-level-client</artifactId>​
    <version>2.9.0</version>​
    </dependency>​
    ​
  • Gradle​
  • ​
    dependencies {​
    implementation 'org.opensearch.client:opensearch-rest-high-level-client:2.9.0'​
    }​
    ​
  • 查询代码​
  • ​
    // 语义查询 low-level-client​
    public SearchResponse search(String indexName, String keyword, int k) throws IOException {​
    String body = "{\n" +​
    " \"query\": {\n" +​
    " \"remote_neural\": {\n" +​
    " \"${查询的向量字段}\": {\n" +​
    " \"query_text\": \"" + keyword + "\",\n" +​
    " \"k\": "+ k +"\n" +​
    " }\n" +​
    " }\n" +​
    " }\n" +​
    "}";​
    String endpointTpl = "%s/_search?search_pipeline=" + pipelineName;​
    Request request = new Request("POST", String.format(endpointTpl, indexName));​
    request.setJsonEntity(body);​
    Response response = client.getLowLevelClient().performRequest(request);​
    // 这里直接通过 JsonXContent 构造 SearchResponse​
    return SearchResponse.fromXContent(JsonXContent.jsonXContent​
    .createParser(null, null, response.getEntity().getContent()));​
    }​
    ​
    ​
    // 语义查询 rest-high-level-client​
    // 1. 先为索引配置默认search_pipeline:​
    PUT ${索引名称}/_settings ​
    {​
    "index.search.default_pipeline" : "${pipelineName}"​
    }​
    ​
    // 2. 配置search_template​
    POST _scripts/search_template_demo​
    {​
    "script": {​
    "lang": "mustache",​
    "source": {​
    "size": "{{size}}",​
    "from": "{{from}}",​
    "query": {​
    "remote_neural": {​
    "${查询的向量字段}": { // 需替换​
    "query_text": "{{keyword}}",​
    "k": "{{k}}"​
    }​
    }​
    }​
    }​
    }​
    }​
    ​
    // 3. 执行查询​
    public SearchResponse search(String indexName, String keyword, int k) throws IOException {​
    SearchTemplateRequest searchTemplateRequest = new SearchTemplateRequest();​
    searchTemplateRequest.setRequest(new SearchRequest().indices("${索引名称}"));​
    searchTemplateRequest.setScriptType(ScriptType.STORED);​
    searchTemplateRequest.setScript("search_template_demo");​
    Map<String, Object> paramMap = Map.of(​
    "from", 0,​
    "size", 20,​
    "keyword", "测试",​
    "k", 10​
    );​
    searchTemplateRequest.setScriptParams(paramMap);​
    SearchTemplateResponse searchTemplateResponse = client.searchTemplate(searchTemplateRequest, RequestOptions.DEFAULT);​
    return searchTemplateResponse.getResponse();​
    }​
    ​
更新文档​
​
//进行数据更新​
IndexData updateData = new IndexData();​
updateData.setFirstName("OpenSearch");​
client.update(r -> r.id("1").doc(updateData).index(index),IndexData.class);​
​
​
//刷盘​
client.indices().refresh(r -> r.index(index));​
​
//查询数据是否更新成功​
GetResponse<IndexData> getRes = client.get(r -> r.id("1").index(index), IndexData.class);​
System.out.println(getRes.source().getFirstName());​
​
删除文档​
​
client.delete(b -> b.index(index).id("1"));​
​
完整样例​
​
import org.apache.hc.client5.http.auth.AuthScope;​
import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;​
import org.apache.hc.client5.http.config.ConnectionConfig;​
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.apache.hc.core5.util.Timeout;​
import org.opensearch.client.json.JsonData;​
import org.opensearch.client.opensearch.OpenSearchClient;​
import org.opensearch.client.opensearch._types.FieldValue;​
import org.opensearch.client.opensearch._types.mapping.KnnVectorProperty;​
import org.opensearch.client.opensearch._types.mapping.Property;​
import org.opensearch.client.opensearch._types.mapping.TextProperty;​
import org.opensearch.client.opensearch._types.mapping.TypeMapping;​
import org.opensearch.client.opensearch.cluster.HealthResponse;​
import org.opensearch.client.opensearch.core.*;​
import org.opensearch.client.opensearch.indices.CreateIndexRequest;​
import org.opensearch.client.opensearch.indices.IndexSettings;​
import org.opensearch.client.opensearch.indices.PutIndicesSettingsRequest;​
import org.opensearch.client.opensearch.indices.RefreshRequest;​
import org.opensearch.client.transport.OpenSearchTransport;​
import org.opensearch.client.transport.httpclient5.ApacheHttpClient5TransportBuilder;​
​
import javax.net.ssl.SSLContext;​
import javax.net.ssl.SSLEngine;​
import java.util.Base64;​
import java.util.concurrent.TimeUnit;​
​
​
public class OSinitClientTest {​
​
public OpenSearchClient initClientIgnoreCA(HttpHost[] hosts, String user, String password) throws Exception {​
​
if (hosts == null || hosts.length == 0) {​
throw new IllegalArgumentException("invalid empty hosts");​
}​
BasicCredentialsProvider provider = new BasicCredentialsProvider();​
for (HttpHost host : hosts) {​
provider.setCredentials(new AuthScope(host), new UsernamePasswordCredentials(user, password.toCharArray()));​
}​
​
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, (x509Certificates, s) -> true).build(); // 跳过 SSL 证书校验​
​
final ApacheHttpClient5TransportBuilder builder = ApacheHttpClient5TransportBuilder.builder(hosts);​
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)​
.setMaxConnTotal(1000) //最大连接数​
.setMaxConnPerRoute(1000) //route 的最大连接数​
.setDefaultConnectionConfig(ConnectionConfig.custom()​
.setTimeToLive(300, TimeUnit.SECONDS) //链接最大存活时间,实例重启后自动平衡负载周期​
.setConnectTimeout(Timeout.ofSeconds(5)) //连接超时时间​
.setSocketTimeout(Timeout.ofSeconds(60))​
.build())​
.build();​
​
return httpClientBuilder​
.setDefaultCredentialsProvider(provider)​
.setConnectionManager(connectionManager);​
});​
​
final OpenSearchTransport transport = builder.build();​
return new OpenSearchClient(transport);​
}​
​
public static void main(String[] args) throws Exception {​
/**​
* 连接实例​
*/​
OpenSearchClient client = new OSinitClientTest().initClientIgnoreCA(​
new HttpHost[]{new HttpHost("<https|http>","<接入点地址>", 9200)},​
"<账号>", "<密码>");​
​
try {​
HealthResponse health = client.cluster().health();​
​
System.out.println("current cluster status is: " + health.status()); // 输出 - current cluster status is: GREEN​
} catch (Exception e) {​
e.printStackTrace();​
}​
​
/**​
* 索引创建,构建一个带有 vector 和 text 的索引​
*/​
String index = "sample-index";​
final KnnVectorProperty nameVector = KnnVectorProperty.of(​
v -> v.dimension(4)​
.method(m -> m.spaceType("cosinesimil")​
.engine("diskann")​
.name("diskann")​
.parameters("L", JsonData.of(30))​
.parameters("R", JsonData.of(32))​
)​
);​
​
client.indices().create(ci -> ci.index(index)​
.mappings(​
builder -> builder.properties(​
"firstName", p -> p.text(t -> t.analyzer("ik_smart"))​
).properties("nameVector", p -> p.knnVector(nameVector))​
)​
.settings(s -> s.index(indexSetting -> indexSetting.knn(true))));​
​
/**​
* 更新索引配置​
*/​
client.indices().putSettings(ps -> ps.index(index)​
.settings(s -> s.autoExpandReplicas("0-all"))​
);​
​
​
/**​
* 写入文档​
*/​
IndexData indexData = new IndexData( "云搜索", new Float[]{ 1.0f,1.0f,1.0f,1.0f});​
client.index(ib -> ib.index(index).id("1").document(indexData));​
​
// 刷新索引保证文档立即可见​
client.indices().refresh(r -> r.index(index));​
​
​
/**​
* 使用 JSON 进行搜索​
*/​
String json_query = "{\"match\":{ \"firstName\": \"云搜索\"}}";​
String encodedJSON = Base64.getEncoder().encodeToString(json_query.getBytes());​
​
SearchResponse<IndexData> search_by_json = client.search(​
r -> r.query(​
q -> q.wrapper(m -> m.query(encodedJSON))),​
IndexData.class​
);​
System.out.println(search_by_json.hits().hits().get(0).source().getFirstName());​
​
​
/**​
* 进行全文搜索​
*/​
SearchResponse<IndexData> search_res = client.search(​
r -> r.query(​
q -> q.match(​
match -> match.field("firstName")​
.query(f -> f.stringValue("云搜索"))​
.analyzer("ik_smart")​
)​
)​
, IndexData.class);​
​
​
System.out.println(search_res.hits().hits().get(0).source().getFirstName());​
​
/**​
* 进行向量搜索​
*/​
SearchResponse<IndexData> vector_res = client.search(​
r -> r.query(​
q -> q.knn(​
knn -> knn.field("nameVector")​
.k(10)​
.vector(new float[]{ 1.0f, 1.0f, 1.0f, 1.0f})​
)​
)​
, IndexData.class);​
System.out.println(vector_res.hits().hits().get(0).source().getFirstName());​
​
/**​
* 更新文档​
*/​
IndexData updateData = new IndexData();​
updateData.setFirstName("OpenSearch");​
client.update(r -> r.id("1").doc(updateData).index(index),IndexData.class);​
​
//刷新索引保证文档立即可见​
client.indices().refresh(r -> r.index(index));​
​
//确定更新结果​
GetResponse<IndexData> getRes = client.get(r -> r.id("1").index(index), IndexData.class);​
System.out.println(getRes.source().getFirstName());​
​
​
/**​
* 删除文档​
*/​
client.delete(b -> b.index(index).id("1"));​
​
/**​
* 删除索引​
*/​
client.indices().delete( r -> r.index(index));​
client.shutdown();​
}​
​
}​
​
class IndexData {​
private String firstName;​
private Float[] nameVector;​
public IndexData() {​
​
}​
public IndexData(String firstName, Float[] nameVector) {​
this.firstName = firstName;​
this.nameVector = nameVector;​
}​
​
public void setFirstName(String firstName) {​
this.firstName = firstName;​
}​
​
public void setNameVector(Float[] nameVector) {​
this.nameVector = nameVector;​
}​
​
public String getFirstName() {​
return this.firstName;​
}​
​
public Float[] getNameVector() {​
return this.nameVector;​
}​
}​
​
​
最近更新时间:2025.09.22 18:43:14
这个页面对您有帮助吗?
有用
有用
无用
无用