🌟 一文掌握《Elasticsearch:7.0 》的 JavaApi

2,616 阅读7分钟

一、什么是《Elasticsearch:7.0 》的 JavaApi

  • 《Elasticsearch:7.0》的Java API主要是指Elasticsearch 7.0版本提供的Java客户端库,它允许Java应用程序与Elasticsearch集群进行交互。通过使用这些API,开发人员可以轻松地执行诸如索引文档、搜索文档、更新文档和删除文档等操作。

  • 在Elasticsearch 7.0中,官方推荐使用新的Java High Level REST Client,它提供了一个更简洁、更直观的API来与Elasticsearch进行通信。这个客户端基于HTTP协议,使用RESTful风格的设计,并且与Elasticsearch的查询DSL(领域特定语言)紧密集成。

二、实战步骤

2.1 前置操作

2.1.1 双打打开elasticsearch.bat,运行Elasticsearch(Window版本)

image.png

image.png

2.1.2 创建一个maven项目,修改pom文件

<dependencies>
    <dependency>
        <groupId>org.elasticsearch</groupId>
        <artifactId>elasticsearch</artifactId>
        <version>7.8.0</version>
    </dependency>
    <!-- elasticsearch的客户端 -->
    <dependency>
        <groupId>org.elasticsearch.client</groupId>
        <artifactId>elasticsearch-rest-high-level-client</artifactId>
        <version>7.8.0</version>
    </dependency>
    <!-- elasticsearch依赖2.x的log4j -->
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-api</artifactId>
        <version>2.8.2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>2.8.2</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.9.9</version>
    </dependency>
    <!-- junit单元测试 -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
</dependencies>

2.1.3 编写ES_Util工具类

public class ES_Util {

    private static RestHighLevelClient esClient;

    public static RestHighLevelClient getClient() {
        // 创建ES客户端
        return esClient = new RestHighLevelClient(
                RestClient.builder(new HttpHost("localhost", 9200, "http"))
        );
    }

    // 关闭ES客户端
    public static synchronized void closeClient() throws IOException {
        if (esClient != null) {
            // 关闭ES客户端
            esClient.close();
            // 设置为null,表示已经关闭
            esClient = null; 
        }
    }
}

2.1.4 编写Dog实体类

public class Dog {
    private String name;
    private String sex;
    private Integer age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

2.2 索引操作

2.2.1 创建索引

① 先用apifox 发生一个get 请求查看名为dog的索引存不存在

http://127.0.0.1:9200/dog

image.png

② 编写测试类 ES_Index_Search

public class ES_Index_Create {
    
    public static void main(String[] args) throws Exception {
        RestHighLevelClient esClient = ES_Util.getClient();

        // 创建索引
        CreateIndexRequest request = new CreateIndexRequest("dog");
        CreateIndexResponse createIndexResponse =
                esClient.indices().create(request, RequestOptions.DEFAULT);
        // 响应状态
        boolean acknowledged = createIndexResponse.isAcknowledged();
        System.out.println("索引创建结果 :" + acknowledged);
        ES_Util.closeClient();

    }
}

③ 查看运行结果

image.png

④ 继续用apifox查看dog这个索引

image.png

2.2.2 删除索引

① 编写测试类 ES_Index_Delete

public class ES_Index_Delete {
    public static void main(String[] args) throws Exception {
        RestHighLevelClient esClient = ES_Util.getClient();
        // 查询索引
        DeleteIndexRequest request = new DeleteIndexRequest("dog");
        AcknowledgedResponse response = esClient.indices().delete(request, RequestOptions.DEFAULT);
        // 响应状态
        System.out.println("索引删除结果: " + response.isAcknowledged());
        ES_Util.closeClient();
    }
}

② 查看运行结果

image.png

2.2.3 查看索引

① 编写测试类 ES_Index_Search

public class ES_Index_Search {
    public static void main(String[] args) throws Exception {
        RestHighLevelClient esClient = ES_Util.getClient();
        // 查询索引
        GetIndexRequest request = new GetIndexRequest("dog");
        GetIndexResponse getIndexResponse =
                esClient.indices().get(request, RequestOptions.DEFAULT);
        // 响应状态
        System.out.println("getIndexResponse.getAliases() = " + getIndexResponse.getAliases());
        System.out.println("getIndexResponse.getMappings() = " + getIndexResponse.getMappings());
        System.out.println("getIndexResponse.getSettings() = " + getIndexResponse.getSettings());
        ES_Util.closeClient();
    }
}

② 查看运行结果

image.png

③ 再执行一次索引创建并查看索引

image.png

2.3 文档操作

2.3.1 文档创建

① 编写测试类 ES_Doc_Insert

public class ES_Doc_Insert {
    public static void main(String[] args) throws Exception {
        RestHighLevelClient esClient = ES_Util.getClient();
        // 创建索引
        IndexRequest request = new IndexRequest();
        request.index("dog").id("100");

        Dog dog = new Dog();
        dog.setName("小黄");
        dog.setAge(3);
        dog.setSex("雄");

        // 向ES插入数据,必须将数据转换位JSON格式
        ObjectMapper mapper = new ObjectMapper();
        String userJson = mapper.writeValueAsString(dog);
        request.source(userJson, XContentType.JSON);
        IndexResponse response = esClient.index(request, RequestOptions.DEFAULT);
        System.out.println("文档的操作结果:" + response.getResult());
        ES_Util.closeClient();
    }
}

② 查看运行结果

image.png

④ 用apifox查看dog这个索引

http://127.0.0.1:9200/dog/_search

image.png

2.3.2 文档批量创建

① 编写测试类 ES_Doc_Insert_Batch

public class ES_Doc_Insert_Batch {
    public static void main(String[] args) throws Exception {
        RestHighLevelClient esClient = ES_Util.getClient();
        // 批量插入数据
        BulkRequest request = new BulkRequest();
        Dog dog = new Dog();
        dog.setName("小黄");
        dog.setAge(3);
        dog.setSex("雄");

        Dog dog2 = new Dog();
        dog2.setName("小白");
        dog2.setAge(2);
        dog2.setSex("雌");

        // 向ES插入数据,必须将数据转换位JSON格式
        ObjectMapper mapper = new ObjectMapper();
        String userJson = mapper.writeValueAsString(dog);
        String userJson2 = mapper.writeValueAsString(dog2);

        request.add(new IndexRequest().index("dog").id("100").source(userJson, XContentType.JSON));
        request.add(new IndexRequest().index("dog").id("101").source(userJson2, XContentType.JSON));
        // 执行批量插入
        BulkResponse response = esClient.bulk(request, RequestOptions.DEFAULT);
        System.out.println("执行时间: " + response.getTook());
        System.out.println("response.getItems() = " + response.getItems());
        ES_Util.closeClient();
    }
}

② 查看运行结果

image.png

③ 用apifox查看dog这个索引

image.png

2.3.3 文档删除

① 编写测试类 ES_Doc_Delete

public class ES_Doc_Delete {
    public static void main(String[] args) throws Exception {
        RestHighLevelClient esClient = ES_Util.getClient();
        DeleteRequest request = new DeleteRequest();
        request.index("dog").id("100");
        DeleteResponse response = esClient.delete(request, RequestOptions.DEFAULT); 
        System.out.println("删除文档的内容:" + response);
        ES_Util.closeClient();
    }
}

② 查看运行结果

image.png

③ 用apifox查看dog这个索引

image.png

2.3.4 文档批量删除

① 先执行批量新增文档:新增两个文档id分别为1000,10001

image.png

② 用apifox查看dog这个索引

image.png

③ 编写测试类 ES_Doc_Delete_Batch

public class ES_Doc_Delete_Batch {
    public static void main(String[] args) throws Exception {
        RestHighLevelClient esClient = ES_Util.getClient();
        // 批量删除数据
        BulkRequest request = new BulkRequest();
        request.add(new DeleteRequest().index("dog").id("1001"));
        request.add(new DeleteRequest().index("dog").id("1002"));
        BulkResponse response = esClient.bulk(request, RequestOptions.DEFAULT);
        System.out.println("执行时间: " + response.getTook());
        System.out.println("response.getItems() = " + response.getItems());
        ES_Util.closeClient();
    }
}

④ 查看运行结果

image.png

⑤ 用apifox查看dog这个索引

image.png

2.3.5 文档修改

① 编写测试类 ES_Doc_Update

public class ES_Doc_Update {
    public static void main(String[] args) throws Exception {
        RestHighLevelClient esClient = ES_Util.getClient();

        // 假设我们要更新id为100的dog索引文档
        UpdateRequest updateRequest = new UpdateRequest();
        updateRequest.index("dog").id("101");

        Dog updatedDog = new Dog();
        updatedDog.setName("小红");
        updatedDog.setSex("女"); 
        updatedDog.setAge(2);

        // 将更新的Dog对象转换为JSON字符串
        ObjectMapper mapper = new ObjectMapper();
        String updatedDogJson = mapper.writeValueAsString(updatedDog);

        // 使用新的JSON字符串更新文档
        updateRequest.doc(updatedDogJson, XContentType.JSON);

        // 发送更新请求并获取响应
        UpdateResponse updateResponse = esClient.update(updateRequest, RequestOptions.DEFAULT);
        System.out.println("文档更新结果:" + updateResponse.getResult());

        // 关闭Elasticsearch客户端连接
        ES_Util.closeClient();
    }
}

② 查看运行结果

image.png

③ 用apifox查看dog这个索引

image.png

2.3.6 文档查询

① 编写测试类 ES_Doc_Get

public class ES_Doc_Get {
    public static void main(String[] args) throws Exception {
        RestHighLevelClient esClient = ES_Util.getClient();
        // 查询数据
        GetRequest request = new GetRequest();
        request.index("dog").id("101");
        GetResponse response = esClient.get(request, RequestOptions.DEFAULT);
        System.out.println("response.getSourceAsString() = " + response.getSourceAsString());
        ES_Util.closeClient();
    }
}

② 查看运行结果

image.png

2.3.7 文档条件查询

1)查询索引中全部的数据

① 先执行批量插入,新增id为1000,10001的文档

image.png

② 实现代码

 RestHighLevelClient esClient = ES_Util.getClient();
 // 1. 查询索引中全部的数据
SearchRequest request = new SearchRequest();
request.indices("dog");
request.source(new SearchSourceBuilder().query(QueryBuilders.matchAllQuery()));
SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
SearchHits hits = response.getHits();
 System.out.println("hits.getTotalHits() = " + hits.getTotalHits());
 System.out.println("response.getTook() = " + response.getTook());
 for ( SearchHit hit : hits ) {
     System.out.println("hit.getSourceAsString() = " + hit.getSourceAsString());
 }

③ 查看运行结果 image.png

2)条件查询 : termQuery

① 实现代码

SearchRequest request = new SearchRequest();
request.indices("dog");
request.source(new SearchSourceBuilder().query(QueryBuilders.termQuery("age", 2)));
SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
SearchHits hits = response.getHits();
System.out.println("hits.getTotalHits() = " + hits.getTotalHits());
System.out.println("response.getTook() = " + response.getTook());
for ( SearchHit hit : hits ) {
     System.out.println("hit.getSourceAsString() = " + hit.getSourceAsString());
 }

② 查看运行结果

image.png

3)分页查询

① 实现代码

SearchRequest request = new SearchRequest();
request.indices("dog");
SearchSourceBuilder builder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
// (当前页码-1)*每页显示数据条数
builder.from(0);
builder.size(2);
request.source(builder);
SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
SearchHits hits = response.getHits();
System.out.println("hits.getTotalHits() = " + hits.getTotalHits());
System.out.println("response.getTook() = " + response.getTook());
for ( SearchHit hit : hits ) {
    System.out.println("hit.getSourceAsString() = " + hit.getSourceAsString());
}

② 查看运行结果

image.png

4)查询排序

① 实现代码

SearchRequest request = new SearchRequest();
request.indices("dog");
SearchSourceBuilder builder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
//根据年龄降序
builder.sort("age", SortOrder.DESC);
request.source(builder);
SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
SearchHits hits = response.getHits();
 System.out.println("hits.getTotalHits() = " + hits.getTotalHits());
 System.out.println("response.getTook() = " + response.getTook());
 for ( SearchHit hit : hits ) {
     System.out.println("hit.getSourceAsString() = " + hit.getSourceAsString());
 }

② 查看运行结果

image.png

5)过滤字段

image.png ① 实现代码

SearchRequest request = new SearchRequest();
request.indices("dog");
SearchSourceBuilder builder = new SearchSourceBuilder().query(QueryBuilders.matchAllQuery());
// 过滤字段
String[] excludes = {"age"};
String[] includes = {};
builder.fetchSource(includes, excludes);
request.source(builder);
SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
SearchHits hits = response.getHits();
System.out.println("hits.getTotalHits() = " + hits.getTotalHits());
System.out.println("response.getTook() = " + response.getTook());
for ( SearchHit hit : hits ) {
     System.out.println("hit.getSourceAsString() = " + hit.getSourceAsString());
 }

② 查看运行结果

image.png

6)组合查询

① 实现代码

SearchRequest request = new SearchRequest();
request.indices("dog");
SearchSourceBuilder builder = new SearchSourceBuilder();
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
//must 必须匹配 should 至少匹配一个
//boolQueryBuilder.must(QueryBuilders.matchQuery("age", 3));
//boolQueryBuilder.must(QueryBuilders.matchQuery("sex", "雄"));
boolQueryBuilder.should(QueryBuilders.matchQuery("age", 2));
boolQueryBuilder.should(QueryBuilders.matchQuery("age", 3));
builder.query(boolQueryBuilder);
request.source(builder);
SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
SearchHits hits = response.getHits();
 System.out.println("hits.getTotalHits() = " + hits.getTotalHits());
 System.out.println("response.getTook() = " + response.getTook());
 for ( SearchHit hit : hits ) {
     System.out.println("hit.getSourceAsString() = " + hit.getSourceAsString());
 }

② 查看运行结果

image.png

7)范围查询

image.png ① 实现代码

 SearchRequest request = new SearchRequest();
 request.indices("dog");
 SearchSourceBuilder builder = new SearchSourceBuilder();
 RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery("age");
 rangeQuery.gte(3);
// rangeQuery.lt(50);
 builder.query(rangeQuery);
 request.source(builder);
 SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
 SearchHits hits = response.getHits();
 System.out.println("hits.getTotalHits() = " + hits.getTotalHits());
 System.out.println("response.getTook() = " + response.getTook());
 for ( SearchHit hit : hits ) {
      System.out.println("hit.getSourceAsString() = " + hit.getSourceAsString());
  }

② 查看运行结果 image.png

8)范围查询

① 实现代码

SearchRequest request = new SearchRequest();
request.indices("dog");
SearchSourceBuilder builder = new SearchSourceBuilder();
builder.query(QueryBuilders.fuzzyQuery("name", "小白").fuzziness(Fuzziness.TWO));
request.source(builder);
SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
SearchHits hits = response.getHits();
 System.out.println("hits.getTotalHits() = " + hits.getTotalHits());
 System.out.println("response.getTook() = " + response.getTook());
 for ( SearchHit hit : hits ) {
     System.out.println("hit.getSourceAsString() = " + hit.getSourceAsString());
 }

② 查看运行结果

image.png

9)高亮查询

① 实现代码

SearchRequest request = new SearchRequest();
request.indices("dog");
SearchSourceBuilder builder = new SearchSourceBuilder();
TermsQueryBuilder termsQueryBuilder = QueryBuilders.termsQuery("name", "小");
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.preTags("<font color='red'>");
highlightBuilder.postTags("</font>");
highlightBuilder.field("name");
builder.highlighter(highlightBuilder);
builder.query(termsQueryBuilder);
request.source(builder);
SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
SearchHits hits = response.getHits();
 System.out.println("hits.getTotalHits() = " + hits.getTotalHits());
 System.out.println("response.getTook() = " + response.getTook());
 for ( SearchHit hit : hits ) {
     System.out.println("hit.getSourceAsString() = " + hit.getSourceAsString());
 }

② 查看运行结果

image.png

10)聚合查询

① 实现代码

SearchRequest request = new SearchRequest();
request.indices("dog");
SearchSourceBuilder builder = new SearchSourceBuilder();
AggregationBuilder aggregationBuilder = AggregationBuilders.max("maxAge").field("age"); // 更正为max,且命名清晰
builder.aggregation(aggregationBuilder);
request.source(builder);
SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
// 从响应中获取聚合结果
Aggregations aggregations = response.getAggregations();
Max maxAge = aggregations.get("maxAge"); // 使用与上面相同的聚合名称
// 打印最大年龄的值
if (maxAge != null) {
    double maxAgeValue = maxAge.getValue();
    System.out.println("最大年龄的值是: " + maxAgeValue);
} else {
    System.out.println("未找到聚合结果");
}

② 查看运行结果

image.png

11) 分组查询

SearchRequest request = new SearchRequest();
request.indices("dog");
SearchSourceBuilder builder = new SearchSourceBuilder();
AggregationBuilder aggregationBuilder = AggregationBuilders.terms("ageGroup").field("age");
builder.aggregation(aggregationBuilder);
request.source(builder);
SearchResponse response = esClient.search(request, RequestOptions.DEFAULT);
// 从响应中获取聚合结果
Aggregations aggregations = response.getAggregations();
Terms ageGroup = aggregations.get("ageGroup"); // 使用与聚合相同的名称
// 打印根据年龄分组的结果
if (ageGroup != null) {
    for (Terms.Bucket bucket : ageGroup.getBuckets()) {
        System.out.println("年龄组的值: " + bucket.getKeyAsString() + ", 文档数: " + bucket.getDocCount());
    }
} else {
    System.out.println("未找到聚合结果");
}

image.png

三、总结

  • 本文详细阐述了《Elasticsearch:7.0》的Java API及其在实战中的应用。

  • 本文首先解释了什么是Elasticsearch 7.0的Java API,并指出其是Java应用程序与Elasticsearch集群交互的桥梁。

  • 接着,通过前置操作、索引操作、文档操作等步骤,系统地介绍了如何使用这些API进行Elasticsearch的索引创建、删除、查看,以及文档的创建、批量创建、删除、批量删除、修改、查询、条件查询等操作。其中,条件查询部分详细展示了各种查询场景,包括全量查询、词条查询、分页查询、排序查询、过滤字段查询、组合查询、范围查询、高亮查询以及聚合与分组查询等,为读者提供了丰富的查询示例。