Java客户端分为低级客户端和高级客户端两种。低级客户端兼容所有版本的ES,但其需要提供JSON字符串,因此这种开发方式比较低效。高级客户端是基于低级客户端开发出来的,屏蔽了底层技术,使用户可以更专注于搜索业务,这是官方推荐的开发方式。
Java客户端的使用
1、创建Maven工程,导入依赖:
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>7.13.2</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.13.2</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>compile</scope>
</dependency>
2、测试RestHighLevelClient
@Test
public void testEsClient(){
String hostsStr = "127.0.0.1:9200";
HttpHost[] hosts = Arrays.stream(hostsStr.split(",")).map(host->{
String[] hostParts = host.split(":");
String hostName = hostParts[0];
int port = Integer.parseInt(hostParts[1]);
return new HttpHost(hostName,port,HttpHost.DEFAULT_SCHEME_NAME);
}).filter(Objects::nonNull).toArray(HttpHost[]::new);
RestHighLevelClient restHighLevelClient = new RestHighLevelClient(RestClient.builder(hosts));
System.out.println(restHighLevelClient);
}
Java带验证客户端的使用
在生产环境下,ES一般都会开启安全验证功能,由于ES Java客户端使用的也是HTTP标准规范中的认证机制,因此在建立客户端和服务端的连接时需要一组凭证用于鉴定用户身份,而这组凭证就是用户名和密码。
CredentialsProvider类是一个凭证类,通过CredentialsProvider.setCredentials()方法可以设置凭证。UsernamePasswordCredentials类可以用明文的形式来表示认证凭证,通过CredentialsProvider.setCredentials()方法设置它的实例,就可以完成凭证的构建。
当使用RestClient.builder()方法构建完RestClientBuilder实例后,需要调用RestClient Builder.setHttpClientConfigCallback()方法完成认证。RestClientBuilder.setHttpClientConfig Callback()方法需要传入一个RestClientBuilder.HttpClientConfigCallback实例,构造完该实例后,可以在该实例的customizeHttpClient()方法中传输之前创建的凭证。如下所示代码:
@Test
public void testEsClientWithAuth(){
String hostStr = "127.0.0.1:9200";
String username = "";
String password = "";
HttpHost[] hosts = Arrays.stream(hostStr.split(",")).map(host->{
String[] hostPart = host.split(":");
String hostName = hostPart[0];
int port = Integer.parseInt(hostPart[1]);
return new HttpHost(hostName,port,HttpHost.DEFAULT_SCHEME_NAME);
}).filter(Objects::nonNull).toArray(HttpHost[]::new);
//生成凭证
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY,new UsernamePasswordCredentials(username,password));
RestHighLevelClient restHighLevelClient = new RestHighLevelClient(RestClient.builder(hosts).setHttpClientConfigCallback(new RestClientBuilder.HttpClientConfigCallback() {
@Override
public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpAsyncClientBuilder) {
httpAsyncClientBuilder.disableAuthCaching();
return httpAsyncClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
}
}));
System.out.println(restHighLevelClient);
}
Java客户端搜索文档
使用Rest搜索时,首先需要创建一个SearchSourceBuilder实例,然后创建查询实例并将其传送给SearchSourceBuilder,此处创建的查询实例相当于构建DSL,接着创建SearchRequest实例,最后将SearchSourceBuilder传送给SearchRequest。
请求构建完成后,需要使用Client发送请求获取结果。我们知道,在使用curl命令和Kibana时,ES返回的JSON搜索结果是封装在hits中的。同样,Java API获取的返回结果是封装在SearchHits中的。遍历SearchHits,通过其中的每一个元素可以获取搜索命中的每个文档的信息,诸如文档_id、得分和文档内容等。在Service中完整的搜索代码如下:
@Test
public void testFindHotel() throws IOException {
String hostStr = "127.0.0.1:9200";
HttpHost[] httpHosts = Arrays.stream(hostStr.split(",")).map(host->{
String[] hostPart = host.split(":");
String hostName = hostPart[0];
int port = Integer.parseInt(hostPart[1]);
return new HttpHost(hostName,port,HttpHost.DEFAULT_SCHEME_NAME);
}).filter(Objects::nonNull).toArray(HttpHost[]::new);
RestHighLevelClient restHighLevelClient = new RestHighLevelClient(RestClient.builder(httpHosts));
//客户端请求
SearchRequest searchRequest = new SearchRequest("hotel");
//构建query
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.matchQuery("title","java旅馆"));
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
RestStatus status = searchResponse.status();
if(status==RestStatus.OK){
SearchHits hits = searchResponse.getHits();
for (SearchHit searchHit:hits){
System.out.println("id:"+searchHit.getId()+" index:"+searchHit.getIndex()+" score:"+searchHit.getScore());
Map<String, Object> sourceAsMap = searchHit.getSourceAsMap();
System.out.println("title:"+sourceAsMap.get("title")+" city:"+sourceAsMap.get("city"));
}
}
}