zoukankan      html  css  js  c++  java
  • Jest — ElasticSearch Java 客户端

    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/

    在这里插入图片描述

  • 相关阅读:
    CSU 1605 数独
    HDU 1426 dancing links解决数独问题
    FZU 1686 dlx重复覆盖
    hdu 2295 dlx重复覆盖+二分答案
    zju 3209 dancing links 求取最小行数
    hust 1017 dancing links 精确覆盖模板题
    POJ 1724 二维费用最短路
    【转载】学习总结:初等数论(3)——原根、指标及其应用
    【poj3415-Common Substrings】sam子串计数
    【hdu4436/LA6387-str2int】sam处理不同子串
  • 原文地址:https://www.cnblogs.com/liululee/p/11075432.html
Copyright © 2011-2022 走看看