草庐IT

优秀的Elasticsearch Java 客户端-Jest

爱游泳的老白 2023-10-15 原文

一、简介

任何使用过Elasticsearch的人都知道,使用他们的RESTful serach 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库 将作为传递依赖项包含在内。

3. 使用 Jest 客户端

在本节中,我们将了解如何使用 Jest 客户端通过 Elasticsearch 执行常见任务。

要使用 Jest 客户端,我们只需使用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();
}

这将创建一个连接到本地运行的 Elasticsearch 客户端的 Jest 客户端。虽然这个连接示例很简单,但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. 管理 索引

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

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 客户端使用Index操作类可以轻松索引或创建新文档。Elasticsearch 中的文档只是 JSON 数据,有多种方法可以将 JSON 数据传递给 Jest 客户端进行索引。

对于此示例,让我们使用一个虚构的 Employee 文档:

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

表示 JSON 文档的第一种方法是使用 Java String。虽然我们可以手动创建 JSON 字符串,但我们必须注意正确的格式、大括号和转义引号字符。

因此,使用诸如Jackson之类的 JSON 库来构建我们的 JSON 结构然后转换为String会更容易:

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 数据并将其传递给Index操作:

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 客户端可以接受代表要索引的文档的任何 POJO。假设我们有一个Employee类:

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

我们可以将此类的实例直接传递给索引构建器:

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 客户端从 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 中通过Search操作实现的。

Jest 客户端支持完整的 Elasticsearch 查询 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库。

通过Search操作,可以使用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());

它接受与我们之前看到的Index操作相同的 JSON 表示,从而可以轻松地在两个操作之间共享代码。

3.5. 删除 文档

使用Delete操作从索引中删除文档。它只需要一个索引名称和文档 ID:

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

4.批量操作

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

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

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 客户端还支持异步操作,这意味着我们可以使用非阻塞 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 客户端将在操作完成时调用此对象。该接口有两种方法—完成失败—分别允许处理操作的成功或失败。

六,结论

在本教程中,我们简要介绍了 Jest 客户端,它是 Elasticsearch 的 RESTful Java 客户端。

虽然我们只介绍了它的一小部分功能,但很明显 Jest 是一个强大的 Elasticsearch 客户端。其流畅的构建器类和 RESTful 接口使其易于学习,并且其对 Elasticsearch 接口的全面支持使其成为本机客户端的有力替代品。


<<<<<<<<<<<< [完] >>>>>>>>>>>>

有关优秀的Elasticsearch Java 客户端-Jest的更多相关文章

  1. ruby - 在 TCPServer (Ruby) 中,我如何从客户端获取 IP/MAC? - 2

    我想在Ruby的TCPServer中获取客户端的IP地址。以及(如果可能的话)MAC地址。例如,Ruby中的时间服务器,请参阅评论。tcpserver=TCPServer.new("",80)iftcpserverputs"Listening"loopdosocket=tcpserver.acceptifsocketThread.newdoputs"Connectedfrom"+#HERE!HowcanigettheIPAddressfromtheclient?socket.write(Time.now.to_s)socket.closeendendendend非常感谢!

  2. ruby-on-rails - 为什么我必须在使用客户验证器后重新加载 rspec 中的记录? - 2

    我有一个模型User,它在创建后的回调中创建了选项#Userhas_one:user_optionsafter_create:create_optionsprivatedefcreate_optionsUserOptions.create(user:self)end我对此有一些简单的Rspec覆盖:describe"newuser"doit"createsuser_optionsaftertheuseriscreated"douser=create(:user)user.user_options.shouldbe_kind_of(UserOptions)endend一切正常,直到我将自

  3. ruby - 如何获得带有 SSL 客户端证书的 HTTPS 请求以与 Ruby EventMachine 一起使用? - 2

    我正在尝试使用RubyEventMachine访问使用SSL证书身份验证的HTTPSWeb服务,但我没有让它工作。我编写了以下简单代码块来对其进行端到端测试:require'rubygems'require'em-http'EventMachine.rundourl='https://foobar.com/'ssl_opts={:private_key_file=>'/tmp/private.key',:cert_chain_file=>'/tmp/ca.pem',:verify_peer=>false}http=EventMachine::HttpRequest.new(url).g

  4. ruby-on-rails - 在 Ruby on Rails 应用程序中使用客户端 SSL - 2

    我正在为需要与API建立SSL连接的客户端开发应用程序。我得到了三个文件;一个信任根证书(.cer)文件、一个中间证书(.cer)文件和一个签名的响应文件。我得到的安装说明与IIS或Javakeytool程序有关;我正在用RubyonRails构建应用程序,所以这两种方法都不是一个选项(据我所知)。证书由运行API服务的组织自签名,看来我获得了客户端证书以相互验证https连接。我不确定如何使用我的应用程序中的证书连接和使用API签名响应文件的作用我读过"Usingaself-signedcertificate"和thisarticleonOpenSSLinRuby但两者似乎都不是很到

  5. ruby - 为什么这个启用 SSL 的 Ruby 服务器/客户端测试有效? - 2

    我正在努力在Ruby中创建启用SSL的服务器,以及与服务器一起使用的相应Ruby客户端。为了进行测试,我使用以下命令创建了自己的根CA证书。$:~/devel/ssl-test/ssl/CA$opensslgenrsa-outTestCA.key2048GeneratingRSAprivatekey,2048bitlongmodulus............+++...........................+++eis65537(0x10001)$:~/devel/ssl-test/ssl/CA$opensslreq-new-keyTestCA.key-outTestCA.

  6. ruby-on-rails - 在处理电子邮件回复时,我怎样才能忽略任何电子邮件客户端细节和历史记录? - 2

    我有一个通过IMAP处理传入电子邮件的Rails应用程序。当前使用一种方法来搜索TMail对象的各个部分以查找给定的content_type:defself.search_parts_for_content_type(parts,content_type='text/html')parts.eachdo|part|ifpart.content_type==content_typereturnpart.bodyelseifpart.multipart?ifbody=self.search_parts_for_content_type(part.parts,content_type)ret

  7. ruby-on-rails - 什么是可以轻松集成到现有应用程序的优秀 Ruby on Rails 论坛? - 2

    什么是可以轻松集成到现有应用程序的优秀开源RoR3论坛?可选功能:OpenID支持Haml/SCSS模板支持表情符号、YouTube、图片等我可能会对其进行大量更改,而且我在Ruby方面仍然很薄弱,所以干净、带注释的代码以及良好的实践会很棒。谢谢:) 最佳答案 最近我在搜索类似的功能并遇到了discourse.您绝对应该检查一下。Discourseisthe100%opensource,next-generationdiscussionplatformbuiltforthenextdecadeoftheInternet.Whenev

  8. ruby-on-rails - Ruby on Rails & Prawn PDF - 创建客户名单 - 2

    我正在尝试使用Prawn生成PDF报告,我可以通过传递单个ID轻松地让它对表演Action进行报告,但我想生成一个包含其中每条记录的报告。就像一个标准的railsscaffold索引页面。使用rails它看起来像这样:简单!但我不确定如何用Prawn做到这一点..类似于:defindex@customer=Customer.allrespond_todo|format|format.htmlPrawn::Document.generate("customer_list.pdf")do|pdf|pdf.text"#{@customer.id}"pdf.text"#{@customer.n

  9. ruby - 具有 HTTPS、SSL 客户端证书和 Keep-Alive 支持的 Ruby HTTP 库? - 2

    我正在尝试用Ruby编写一个HTTPS客户端。它将使用HTTPS连接到服务器,传递身份验证token(通过单独的登录过程获得)和SSL客户端证书。我正在使用rest-client执行以下操作:client=RestClient::Resource.new(url,:ssl_client_cert=>OpenSSL::X509::Certificate.new(File.read('./certificate/client-2048.pem')),:ssl_client_key=>OpenSSL::PKey::RSA.new(File.read('./certificate/client

  10. ruby-on-rails - 如何在 Ruby 中创建 Web 套接字客户端? - 2

    我需要从我的Rails应用程序向websocket服务器发送一些数据。意思是,我制作了一个Rails网络服务,当进行某些API调用时,我需要将一些数据发布到网络套接字服务器。是否有任何预建库可以在Rails中轻松创建Web套接字客户端? 最佳答案 Ruby客户端和服务器:https://github.com/igrigorik/em-websocket还有:https://github.com/mplatov/ruby-websocket-client 关于ruby-on-rails-如

随机推荐