1. 介绍

任何使用过Elasticsearch的人都知道,使用基于rest的搜索API构建查询可能是单调乏味且容易出错的。

在本教程中,我们将研究Jest,一个用于Elasticsearch的HTTP Java客户端。Elasticsearch提供了自己原生的Java客户端,然而 Jest提供了更流畅的API和更容易使用的接口。

2. Maven 依赖

我们需要做的第一件事是导入Jest库到我们的POM文件中:

<dependency>
<groupId>io.searchbox</groupId>
<artifactId>jest</artifactId>
<version>6.3.1</version>
</dependency>

Jest的版本是遵循Elasticsearch的主版本号的。
这将确保客户端和服务端之间的兼容性。

通过包含Jest依赖项,相应的[Elasticsearch库](https://search.maven.org/search?q=g:org.elasticsearch a:elasticsearch)将被包含为传递依赖项。

3. 使用Jest Client

在本节中,我们将研究如何使用Jest client执行Elasticsearch中的常见任务。

要使用Jest client,我们只需使用 JestClientFactory 创建一个 JestClient 对象。这些对象的创建开销很高,而且是线程安全的,因此我们将创建一个可以在整个应用程序中共享的单例实例:

public JestClient jestClient() {
JestClientFactory factory = new JestClientFactory();
factory.setHttpClientConfig(
new HttpClientConfig.Builder("http://localhost:9200")
.multiThreaded(true)
.defaultMaxTotalConnectionPerRoute(2)
.maxTotalConnection(10)
.build());
return factory.getObject();
}

这里将创建一个Jest client,该客户端连接到本地运行的Elasticsearch。虽然这个连接示例很简单,但是Jest还完全支持代理、SSL、身份验证,甚至节点发现。

JestClient 类是通用类,只有少数公共方法。我们将使用的一个主要方法是execute,它接受Action接口的一个实例。Jest客户端提供了几个构建器类来帮助创建与Elasticsearch交互的不同操作。

所有Jest调用的结果都是JestResult的一个实例。 我们可以通过调用 issucceeded 方法来检查是否成功。对于失败的操作,我们可以调用GetErrorMessage方法来获取更多详细信息:

JestResult jestResult = jestClient.execute(new Delete.Builder("1").index("employees").build());

if (jestResult.isSucceeded()) {
System.out.println("Success!");
}
else {
System.out.println("Error: " + jestResult.getErrorMessage());
}

3.1. 管理索引

检查索引是否存在,我们使用IndicatesExists操作:

JestResult result = jestClient.execute(new IndicesExists.Builder("employees").build())

创建一个索引,我们使用CreateIndex操作:

jestClient.execute(new CreateIndex.Builder("employees").build());

这将创建一个具有默认设置的索引。我们可以在创建索引时覆盖特定的设置:

Map<String, Object> settings = new HashMap<>();
settings.put("number_of_shards", 11);
settings.put("number_of_replicas", 2);
jestClient.execute(new CreateIndex.Builder("employees").settings(settings).build());

使用ModifyAliases操作创建或更改别名也很简单:

jestClient.execute(new ModifyAliases.Builder(
new AddAliasMapping.Builder("employees", "e").build()).build());
jestClient.execute(new ModifyAliases.Builder(
new RemoveAliasMapping.Builder("employees", "e").build()).build());

3.2. 创建文档

Jest client使用索引操作类索引或创建新文档变得容易。Elasticsearch中的文档只是JSON数据,有多种方法可以将JSON数据传递给Jest client 进行索引。

对于这个例子,让我们使用一个虚构的雇员文档:

{
"name": "Michael Pratt",
"title": "Java Developer",
"skills": ["java", "spring", "elasticsearch"],
"yearsOfService": 2
}

表示JSON文档的第一种方法是使用Java字符串。虽然我们可以手动创建JSON字符串,但我们必须注意正确的格式、大括号和转义引号字符。因此,更容易的方式是使用一个JSON库(如Jackson)来构建我们的JSON结构,然后将其转换为字符串:

ObjectMapper mapper = new ObjectMapper();
JsonNode employeeJsonNode = mapper.createObjectNode()
.put("name", "Michael Pratt")
.put("title", "Java Developer")
.put("yearsOfService", 2)
.set("skills", mapper.createArrayNode()
.add("java")
.add("spring")
.add("elasticsearch"));
jestClient.execute(new Index.Builder(employeeJsonNode.toString()).index("employees").build());

我们还可以使用Java Map 来表示JSON数据,并将其传递给索引操作:

Map<String, Object> employeeHashMap = new LinkedHashMap<>();
employeeHashMap.put("name", "Michael Pratt");
employeeHashMap.put("title", "Java Developer");
employeeHashMap.put("yearsOfService", 2);
employeeHashMap.put("skills", Arrays.asList("java", "spring", "elasticsearch"));
jestClient.execute(new Index.Builder(employeeHashMap).index("employees").build());

最后,Jest client 可以接受表示要索引的文档的任何POJO。假设我们有一个Employee类:

public class Employee {
String name;
String title;
List<String> skills;
int yearsOfService;
}

我们可以把这个类的一个实例直接传递给Index builder:

Employee employee = new Employee();
employee.setName("Michael Pratt");
employee.setTitle("Java Developer");
employee.setYearsOfService(2);
employee.setSkills(Arrays.asList("java", "spring", "elasticsearch"));
jestClient.execute(new Index.Builder(employee).index("employees").build());

3.3. 读取文档

使用Jest client从Elasticsearch访问文档有两种主要方法。首先,如果我们知道文档ID,我们可以使用get操作直接访问它:

jestClient.execute(new Get.Builder("employees", "17").build());

要访问返回的文档,我们必须调用其中一个getSource方法。我们可以将结果作为原始JSON获取,或者将其反序列化为DTO:

Employee getResult = jestClient.execute(new Get.Builder("employees", "1").build())
.getSourceAsObject(Employee.class);

访问文档的其他方法是使用搜索查询,这种方式在Jest中是通过搜索操作实现的。

Jest client 支持全部的 Elasticsearch query DSL。 与索引操作一样,查询被表示为JSON文档,并且有多种执行搜索的方法。

首先,我们可以传递一个表示搜索查询的JSON字符串。提醒一下,我们必须确保字符串是正确转义的,并且是有效的JSON:

String search = "{" +
" \"query\": {" +
" \"bool\": {" +
" \"must\": [" +
" { \"match\": { \"name\": \"Michael Pratt\" }}" +
" ]" +
" }" +
" }" +
"}";
jestClient.execute(new Search.Builder(search).build());

与上面的索引操作一样,我们可以使用Jackson之类的库来构建JSON查询字符串。此外,我们还可以使用原生的Elasticsearch查询操作API。这样做的一个缺点是,我们的应用程序必须依赖于完整的Elasticsearch库。

我们可以使用 getSource 方法来访问搜索操作中匹配的文档。然而,Jest还提供了Hit类,它包装了匹配的文档并提供有关结果的元数据。 使用Hit类,我们可以访问每个结果的附加元数据:得分、路由和解释结果,举几个例子:

List<SearchResult.Hit<Employee, Void>> searchResults =
jestClient.execute(new Search.Builder(search).build())
.getHits(Employee.class);
searchResults.forEach(hit -> {
System.out.println(String.format("Document %s has score %s", hit.id, hit.score));
});

3.4. 更新文档

Jest为更新文档提供了一个简单的Update操作:

employee.setYearOfService(3);
jestClient.execute(new Update.Builder(employee).index("employees").id("1").build());

它接受与我们前面看到的索引操作相同的JSON表示,这使得在两个操作之间共享代码变得很容易。

3.5. 删除文档

从索引中删除文档是使用Delete操作完成的。它只需要索引名和文档ID:

jestClient.execute(new Delete.Builder("17")
.index("employees")
.build());

4. 批量操作

Jest client 同样支持批量操作。 这意味着我们可以通过同时发送多个操作来节省时间和带宽。

使用批量操作,我们可以将任意数量的请求组合成单个调用。我们甚至可以将不同类型的请求组合在一起:

jestClient.execute(new Bulk.Builder()
.defaultIndex("employees")
.addAction(new Index.Builder(employeeObject1).build())
.addAction(new Index.Builder(employeeObject2).build())
.addAction(new Delete.Builder("17").build())
.build());

5. 异步操作

Jest client 同样支持异步操作。 这意味着我们可以使用非阻塞I/O执行上述任何操作。

要异步调用操作,只需使用客户端的executeAsync方法:

jestClient.executeAsync(
new Index.Builder(employeeObject1).build(),
new JestResultHandler<JestResult>() {
@Override public void completed(JestResult result) {
// handle result
}
@Override public void failed(Exception ex) {
// handle exception
}
});

注意,除了(本例中是索引)操作之外,异步流还需要一个JestResultHandler。当操作完成时,Jest client 将调用该对象。该接口有两个方法—完成和失败—分别允许处理操作的成功或失败。

6. 结论

在本教程中,我们简要介绍了Jest client,一个用于Elasticsearch的RESTful Java客户端。虽然我们只介绍了它的一小部分功能,但很明显Jest是一个健壮的Elasticsearch客户端。它的流畅的构建器类和RESTful接口使其易于学习,并且它对Elasticsearch接口的完全支持使其成为原生客户端的一个有力的替代方案。

和往常一样,本教程中的所有代码示例都在我们的Github页面上。

作者:Michael Pratt

译者:huowolf/

Jest — ElasticSearch Java 客户端的更多相关文章

  1. elasticsearch java 客户端之action简介

    上一篇介绍了elasticsearch的client结构,client只是一个门面,在每个方法后面都有一个action来承接相应的功能.但是action也并非是真正的功能实现者,它只是一个代理,它的真 ...

  2. ElasticSearch java客户端更新时出现的错误:NoNodeAvailableException[None of the configured nodes are available

    下午尝试 用ElasticSearch  的java客户端去做数据检索工作,测试了一下批量更新,代码如下: public static void bulkUpdateGoods(List<Goo ...

  3. elasticsearch java客户端api使用(一)

    1.客户端client构建 ​ package com.pz998.app.service.utils; import static org.elasticsearch.common.settings ...

  4. elasticsearch java 客户端之Client简介

    elasticsearch通过构造一个client对外提供了一套丰富的java调用接口.总体来说client分为两类cluster信息方面的client及数据(index)方面的client.这两个大 ...

  5. Elasticsearch java客户端调用cat服务

    开发环境,测试环境,预发环境和生产环境一般相互隔离的,使用开发环境或者测试环境可以使用cat来查看索引的情况 例如: 但预防环境和测试环境是不允许访问的,那怎么办呢? 可以使用后台来查看上述信息,提供 ...

  6. Elasticsearch及java客户端jest使用

    本文使用Github中的Elasticsearch-rtf,已经集成了众多的插件,例如必须使用的中文分词等,可以简单的通过配置来启用中文分词.本文主要分为以下几部分: 1.配置和启用中文分词: 2.定 ...

  7. elasticsearch 口水篇(3)java客户端 - Jest

    elasticsearch有丰富的客户端,java客户端有Jest.其原文介绍如下: Jest is a Java HTTP Rest client for ElasticSearch.It is a ...

  8. elasticsearch 口水篇(4)java客户端 - 原生esClient

    上一篇(elasticsearch 口水篇(3)java客户端 - Jest)Jest是第三方客户端,基于REST Api进行调用(httpClient),本篇简单介绍下elasticsearch原生 ...

  9. elasticsearch系列七:ES Java客户端-Elasticsearch Java client(ES Client 简介、Java REST Client、Java Client、Spring Data Elasticsearch)

    一.ES Client 简介 1. ES是一个服务,采用C/S结构 2. 回顾 ES的架构 3. ES支持的客户端连接方式 3.1 REST API ,端口 9200 这种连接方式对应于架构图中的RE ...

随机推荐

  1. 初识laytpl

    laytpl-精致巧妙的JavaScript模板引擎 这两天在做一个mui项目,列表需要循环很多的数据.在公司同事的指引下认识了这个新的模板--laytpl.我只想说,很好用们很巧妙. 废话不多说,直 ...

  2. set基本用法-----2

    #include<cstdio> #include<iostream> #include<cstdlib> #include<cmath> #inclu ...

  3. js, lambada? 在chrome和node下可以使用

    var a=function(a,c){if(a)c(a)} undefined a(true,(console.log)) VM177:2 Uncaught TypeError: Illegal i ...

  4. 《手把手教你学C语言》学习笔记(6)---数据类型和常量

    计算机中需要保存信息,就需要数据存储,数据的存储就需要划分数据类型.主要包括:基本数据类型.指针类型.构造类型.空类型. 基本类型:整型---主要用来表示整数,可以分为无符号和有符号:又分为基本整型. ...

  5. wxformbuilder

    1.打开wxFormBuilder,按开始一个空项目.您也可以执行File|New来创建新项目2.从Object Properties(对象属性)面板配置项目的设置A.选择产生什么类型的代码. 现在你 ...

  6. 小型web项目的模块化(转)

    背景   目前团队中新的 Web 项目基本都采用了 Vue 或 React ,加上 RN,这些都属于比较重量级的框架,然而对于小型 Web 页面,又显得过大.早期的一些项目则使用了较原始的 HTML ...

  7. Chrome 75 将原生支持图片懒加载

    4 月 6 日,Google 的 Chrome & Web 平台工程经理 Addy Osmani 在个人博客发文,介绍到 <img> 和 <iframe> 的 load ...

  8. Java编程风格学习(一)

    最近在看一本有关Java编程规范的书,书中精炼阐述了使用java语言时应该遵循的一些原则.接下来的一段时间我将在这里总结我的学习内容,也希望这一系列文章能够对有需要的人有所帮助.不考虑任何编码规范的代 ...

  9. Spring IOC(转载)

    学习过Spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC .DI这两个概念是模糊不清的,是很难理解的,今天和大家 ...

  10. Android为什么方法数不能超过65535

    言归正传,来聊聊为什么方法数不能超过65535?搬上Dalvik工程师在SF上的回答,因为在Dalvik指令集里,调用方法的invoke-kind指令中,method reference index只 ...