虽然ES提供了RestfulAPI,任何语言都可以通过RestfulAPI操作ES,Elastic官方则更进一步为Java/Python/.Net等主流语言提供了客户端工具(不包括C++),它基于HTTP客户端库进行了一些封装,使用更为简便。我们这里介绍如何在Java中操作ES。
注:老版本ES存在一个HighLevelRestClient
,在新版本中已经弃用。
在Maven的pom.xml
中,我们需要引入对应ES版本的Java Client,此外还需要引入Jackson依赖用于客户端库的序列化。
<dependency>
<groupId>co.elastic.clients</groupId>
<artifactId>elasticsearch-java</artifactId>
<version>8.2.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.13.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.13.3</version>
</dependency>
Java Client的使用比较简单,然而其API设计个人认为不太好,这里我们直接看一个完整的例子。下面例子中,我们连接一个开启安全配置的ES服务器,并先后执行批量插入和检索操作。
package com.gacfox.demokafka;
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch.core.BulkResponse;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.elasticsearch.core.bulk.BulkOperation;
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
import co.elastic.clients.transport.ElasticsearchTransport;
import co.elastic.clients.transport.rest_client.RestClientTransport;
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.ssl.SSLContextBuilder;
import org.apache.http.ssl.SSLContexts;
import org.elasticsearch.client.RestClient;
import javax.net.ssl.SSLContext;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
try {
// 用户名和密码
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("elastic", "c+6jHy1yo9vjieQ4eqj_"));
// SSL证书
Path caCertificatePath = Paths.get("f:\\http_ca.crt");
CertificateFactory factory = CertificateFactory.getInstance("X.509");
InputStream is = Files.newInputStream(caCertificatePath);
Certificate trustedCa = factory.generateCertificate(is);
is.close();
KeyStore trustStore = KeyStore.getInstance("pkcs12");
trustStore.load(null, null);
trustStore.setCertificateEntry("ca", trustedCa);
SSLContextBuilder sslContextBuilder = SSLContexts.custom().loadTrustMaterial(trustStore, null);
final SSLContext sslContext = sslContextBuilder.build();
// 创建ElasticSearch客户端
RestClient restClient = RestClient
.builder(new HttpHost("192.168.1.164", 9200, "https"))
.setHttpClientConfigCallback(
httpClientBuilder -> httpClientBuilder
.setSSLContext(sslContext)
.setDefaultCredentialsProvider(credentialsProvider))
.build();
ElasticsearchTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper());
ElasticsearchClient client = new ElasticsearchClient(transport);
// 插入文档
List<BulkOperation> bulkOperations = new ArrayList<>();
bulkOperations.add(new BulkOperation.Builder().create((builder) ->
builder.document(new Article("标题1", "内容1")).id("1").index("idx_article")
).build());
bulkOperations.add(new BulkOperation.Builder().create((builder) ->
builder.document(new Article("标题2", "内容2")).id("2").index("idx_article")
).build());
bulkOperations.add(new BulkOperation.Builder().create((builder) ->
builder.document(new Article("标题3", "内容3")).id("3").index("idx_article")
).build());
BulkResponse bulkResponse = client.bulk(builder -> builder.index("idx_article").operations(bulkOperations));
System.out.println(bulkResponse.took());
System.out.println(bulkResponse.items());
// 搜索
SearchResponse<Article> searchResponse = client.search(
builder -> builder
.index("idx_article")
.query(
q -> q.match(
m -> m.field("").query("标题")
)
),
Article.class);
searchResponse.hits().hits().forEach(articleHit -> {
Article article = articleHit.source();
System.out.println(article);
});
// 关闭客户端
transport.close();
restClient.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
代码中的前两部分比较复杂难懂,分别演示了向HTTP客户端加载认证信息和自签名证书,其实都是固定的写法,具体使用时抄上去即可,证书文件可以在服务端ElasticSearch目录下的config/certs
文件夹下找到。如果你连接的ES服务没有SSL加密或是未开启密码验证,则可以去掉上述代码。
插入、检索等操作其实和使用RestfulAPI差不多,只不过是Java Client客户端包为我们封装为了Java代码,这里就不多赘述了。