ElasticSearch搜索引擎-3_学习笔记(2021.5.5)

1.0 学习ElasticSearch-API

1.1.1 ElasticSearch依赖

<!-- ElasticSearch 依赖 -->
<dependency>
    <groupId>org.elasticsearch</groupId>
    <artifactId>elasticsearch</artifactId>
    <version>7.12.1</version>
</dependency>

<!-- ElasticSearch 客户端依赖 -->
<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
    <version>7.12.1</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>

1.1.2 创建ES客户端

class ElasticsearchTests {
    
    private static RestHighLevelClient client;

    @Test
    void contextLoads() throws Exception {
        System.out.println(client);
    }

    /**
     * 操作前创建ES客户端
     *
     * @author: ZhiHao
     * @date: 2021/5/5
     */
    @BeforeAll
    public static void createElasticsearchClient() throws Exception {
        // 创建ES客户端,  默认也是http方式
        HttpHost httpHost = new HttpHost("119.29.Xxx.xxx",9200,"http");
        RestClientBuilder restClientBuilder = RestClient.builder(httpHost);
        client = new RestHighLevelClient(restClientBuilder);
    }
    
    /** 
     * 操作完最终关闭客户端
     *   
     * @author: ZhiHao
     * @date: 2021/5/5 
     */
    @AfterAll
    public static void closeElasticsearchClient() throws Exception {
        // 最终关闭客户端
        client.close();
    }
}

2.0 索引操作

2.1.1 创建索引

	@Test
    public void indexOperate() throws IOException {
        // 使用索引客户端, 创建索引
        CreateIndexResponse indexResponse = client.indices().create(new CreateIndexRequest("my_from_java"), RequestOptions.DEFAULT);
        boolean acknowledged = indexResponse.isAcknowledged();
        log.info("创建索引结果:{}",acknowledged);
    }

2.1.2 查询索引

	@Test
    public void indexOperate() throws IOException {
        // 查询单个索引
        GetIndexResponse oneIndexResponse = client.indices().get(new GetIndexRequest("my_from_java"), RequestOptions.DEFAULT);
        log.info("ES响应的数据:{}",oneIndexResponse.getIndices());
        log.info("ES响应的数据:{}",oneIndexResponse.getAliases());
        log.info("ES响应的数据:{}",oneIndexResponse.getMappings());
        // 查询所有索引
        GetAliasesResponse alias = client.indices().getAlias(new GetAliasesRequest(), RequestOptions.DEFAULT);
        log.info("ES响应的数据:{}",alias.getAliases());
    }

2.1.3 删除索引

	@Test
    public void indexOperate() throws IOException {
        //  删除索引
        AcknowledgedResponse acknowledgedResponse = client.indices().delete(new DeleteIndexRequest("my_from_java2"), RequestOptions.DEFAULT);
        log.info("ES响应的数据:{}",acknowledgedResponse.isAcknowledged());
    }

3.0 映射操作

3.1.1 创建文档数据实体(模型)

/**
 * @Author: ZhiHao
 * @Date: 2021/5/5 19:33
 * @Description: ES文档数据实体
 * @Versions 1.0
 **/
@Data
public class MyFromJava  implements Serializable {

    private String name;
    private Integer age;
    private String sex;
    private String address;
}

3.1.2 创建索引与数据的映射关系

@Test
    public void documentationOperate() throws IOException {
        // 创建映射
        PutMappingRequest putMappingRequest = new PutMappingRequest("my_from_java");
        XContentBuilder builder = XContentFactory.jsonBuilder();
        // 设置映射关系
        builder.startObject();
        {
            builder.startObject("properties");
            {
                builder.startObject("name");
                {
                    builder.field("type", "text");
                    builder.field("index", true);
                }
                builder.endObject();

                builder.startObject("age");
                {
                    builder.field("type", "long");
                    builder.field("index", true);
                }
                builder.endObject();

                builder.startObject("sex");
                {
                    builder.field("type", "text");
                    builder.field("index", false);
                }
                builder.endObject();

                builder.startObject("address");
                {
                    builder.field("type", "text");
                    builder.field("index", true);
                }
                builder.endObject();
            }
            builder.endObject();
        }
        builder.endObject();
        putMappingRequest.source(builder);
        AcknowledgedResponse acknowledgedResponse = client.indices().putMapping(putMappingRequest, RequestOptions.DEFAULT);
        log.info("ES响应的数据:{}",acknowledgedResponse.isAcknowledged());
    }

3.1.3 查看映射

@Test
    public void documentationOperate() throws IOException {
        // 查看映射
        GetMappingsRequest getMappingsRequest = new GetMappingsRequest();
        getMappingsRequest.indices("my_from_java");
        GetMappingsResponse getMappingsResponse = client.indices().getMapping(getMappingsRequest, RequestOptions.DEFAULT);
        ObjectMapper objectMapper = new ObjectMapper();
        log.info("ES响应的数据:{}",objectMapper.writeValueAsString(getMappingsResponse.mappings()));
    }

3.1.4 更新映射

PS: 不能更新已经添加好的映射, 只能新增字段的映射关系

@Test
    public void documentationOperate() throws IOException {
        // 创建映射
        PutMappingRequest putMappingRequest = new PutMappingRequest("my_from_java");
        XContentBuilder builder = XContentFactory.jsonBuilder();
        // 设置映射关系
        builder.startObject();
        {
            builder.startObject("properties");
            {
                builder.startObject("TestUpdate");
                {
                    builder.field("type", "text");
                    builder.field("index", false);
                }
                builder.endObject();
            }
            builder.endObject();
        }
        builder.endObject();
        putMappingRequest.source(builder);
        AcknowledgedResponse acknowledgedResponse = client.indices().putMapping(putMappingRequest, RequestOptions.DEFAULT);
        log.info("ES响应的数据:{}",acknowledgedResponse.isAcknowledged());
    }

4.0 文档操作

4.1.1 保存文档(或全局修改)

@Test
    public void documentationOperate() throws IOException {
        // 保存文档, (存在ID的情况同时也是全局修改)
        IndexRequest indexRequest = new IndexRequest("my_from_java");
        // 设置ID
        indexRequest.id("10086");
        // 构建保存文档数据实体
        MyFromJava myFromJava =new MyFromJava();
        myFromJava.setName("志豪");
        myFromJava.setAge(18);
        myFromJava.setSex("男");
        myFromJava.setAddress("广东省茂名市");
        // 转JSON字符串
        ObjectMapper objectMapper = new ObjectMapper();
        String jsonStr = objectMapper.writeValueAsString(myFromJava);
        // 设置进请求体, 并使用json格式
        indexRequest.source(jsonStr, XContentType.JSON);
        // 发送请求, 获取响应
        IndexResponse indexResponse = client.index(indexRequest, RequestOptions.DEFAULT);
        log.info("ES响应的数据:{}",indexResponse.getIndex());
        log.info("ES响应的数据:{}",indexResponse.getResult());
        log.info("ES响应的数据:{}",indexResponse.getShardInfo());
    }

4.1.2 简单查看单个文档

@Test
    public void documentationOperate() throws IOException {
        // 指定ID查看文档
        GetRequest getRequest = new GetRequest("my_from_java");
        getRequest.id("10086");
        GetResponse documentFields = client.get(getRequest, RequestOptions.DEFAULT);
        log.info("ES响应的数据:{}",documentFields.getId());
        log.info("ES响应的数据:{}",documentFields.getIndex());
        log.info("ES响应的数据:{}",documentFields.getType());
        log.info("ES响应的数据:{}",documentFields.getSourceAsString());
    }

4.1.3 局部修改文档

@Test
    public void documentationOperate() throws IOException {
        // 修改文档
        UpdateRequest updateRequest = new UpdateRequest();
        updateRequest.index("my_from_java").id("100888");
        updateRequest.doc(XContentType.JSON,"name","真好6666");
        UpdateResponse updateResponse = client.update(updateRequest, RequestOptions.DEFAULT);
        log.info("ES响应的数据:{}",updateResponse.getId());
        log.info("ES响应的数据:{}",updateResponse.getResult());
    }

4.1.4 删除文档

@Test
    public void documentationOperate() throws IOException {
        // 指定ID删除文档
        DeleteRequest deleteRequest = new DeleteRequest();
        deleteRequest.index("my_from_java").id("100888");
        DeleteResponse deleteResponse = client.delete(deleteRequest, RequestOptions.DEFAULT);
        log.info("ES响应的数据:{}",deleteResponse.getId());
        log.info("ES响应的数据:{}",deleteResponse.getIndex());
        log.info("ES响应的数据:{}",deleteResponse.getResult());
    }

4.1.5 批量操作

批量添加

@Test
    public void documentationOperate() throws IOException {
        //创建批量新增请求对象
        BulkRequest request = new BulkRequest();
        for (int i = 1; i <= 5; i++) {
            // 保存文档, (存在ID的情况同时也是全局修改)
            IndexRequest indexRequest = new IndexRequest("my_from_java");
            // 设置ID
            indexRequest.id(String.valueOf(i));
            // 构建保存文档数据实体
            MyFromJava myFromJava =new MyFromJava();
            myFromJava.setName("志豪"+i);
            myFromJava.setAge(18);
            myFromJava.setSex("男");
            myFromJava.setAddress("广东省茂名市");
            // 转JSON字符串
            ObjectMapper objectMapper = new ObjectMapper();
            String jsonStr = objectMapper.writeValueAsString(myFromJava);
            // 设置进请求体, 并使用json格式
            indexRequest.source(jsonStr, XContentType.JSON);
            request.add(indexRequest);
        }
        BulkResponse bulkResponse = client.bulk(request, RequestOptions.DEFAULT);
        log.info("ES响应的数据:{}",bulkResponse.getTook());
        log.info("ES响应的数据:{}",bulkResponse.getItems());
    }

批量删除

@Test
    public void documentationOperate() throws IOException {
        //创建批量新增请求对象
        BulkRequest request = new BulkRequest();
        for (int i = 1; i <= 5; i++) {
            DeleteRequest deleteRequest = new DeleteRequest();
            deleteRequest.index("my_from_java").id(String.valueOf(i));
            request.add(deleteRequest);
        }
        BulkResponse bulkResponse = client.bulk(request, RequestOptions.DEFAULT);
        log.info("ES响应的数据:{}",bulkResponse.getTook());
        log.info("ES响应的数据:{}",bulkResponse.getItems());
    }

批量更新

@Test
    public void documentationOperate() throws IOException {
        //创建批量新增请求对象
        BulkRequest request = new BulkRequest();
        for (int i = 1; i <= 5; i++) {
            UpdateRequest updateRequest = new UpdateRequest();
            updateRequest.index("my_from_java").id(String.valueOf(i));
            updateRequest.doc(XContentType.JSON,"name","真好6666"+i);
            request.add(updateRequest);
        }
        BulkResponse bulkResponse = client.bulk(request, RequestOptions.DEFAULT);
        log.info("ES响应的数据:{}",bulkResponse.getTook());
        log.info("ES响应的数据:{}",bulkResponse.getItems());
    }

5.0 高级查询 (语法关键字与笔记2扩展那里查看)

5.1.1 查询当前索引下所有文档

 @Test
    public void queryOperate() throws IOException {
        // 高级查询
        SearchRequest searchRequest = new SearchRequest();
        // 查询那个索引下的文档数据
        searchRequest.indices("my_from_java");
        // 构建查询条件
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //sourceBuilder.query(new MatchAllQueryBuilder());
        // 等同于上面
        sourceBuilder.query(QueryBuilders.matchAllQuery());
        searchRequest.source(sourceBuilder);
        // 执行查询
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        // 获取结果
        SearchHits hits = searchResponse.getHits();
        for (SearchHit hit : hits.getHits()) {
            log.info("ES响应的每条文档数据:{}", hit.getSourceAsString());
        }
        log.info("ES响应的总记录数据:{}", hits.getTotalHits());
        log.info("ES响应的耗时数据:{}", searchResponse.getTook());
    }

5.1.2 匹配查询

其余代码与5.1.1一样

	// 条件匹配查询- 名称包含有6666的为符合
        sourceBuilder.query(QueryBuilders.matchQuery("name","6666"));
        searchRequest.source(sourceBuilder);

5.1.3 多字段匹配查询

其余代码与5.1.1一样

// 条件匹配查询- multiMatchQuery 与 matchQuery 类似,不同的是它可以在多个字段中查询
        sourceBuilder.query(QueryBuilders.multiMatchQuery("zhihao","name","nickname"));
        searchRequest.source(sourceBuilder);

5.1.4 关键字精确查询

其余代码与5.1.1一样

// 条件匹配查询- termQuery 查询,精确的关键词匹配查询,不对查询条件进行分词。 
        sourceBuilder.query(QueryBuilders.termQuery("name","志豪"));
        searchRequest.source(sourceBuilder);

5.1.5 分页查询

其余代码与5.1.1一样

		// 查询所有
        searchSourceBuilder.query(QueryBuilders.matchAllQuery());
        // 分页
        int pageNum = 1;
        int pageSize = 3;
        searchSourceBuilder.from((pageNum-1)*pageSize);
        searchSourceBuilder.size(pageSize);
        searchRequest.source(searchSourceBuilder);
    }

5.1.6 排序查询

其余代码与5.1.1一样

 		// 查询所有
        searchSourceBuilder.query(QueryBuilders.matchAllQuery());
        // 单字段排序
        searchSourceBuilder.sort("age", SortOrder.DESC);
        searchRequest.source(searchSourceBuilder);
-------------------------------------------------------------------------------------------
		// 多字段排序
        ArrayList<SortBuilder<?>> sorts = new ArrayList<>();
        FieldSortBuilder fieldSortBuilder1 = new FieldSortBuilder("age");
        fieldSortBuilder1.order(SortOrder.ASC);
        FieldSortBuilder fieldSortBuilder2 = new FieldSortBuilder("fraction");
        fieldSortBuilder2.order(SortOrder.DESC);
        sorts.add(fieldSortBuilder1);
        sorts.add(fieldSortBuilder2);
        searchSourceBuilder.sort(sorts);
        searchRequest.source(searchSourceBuilder);

5.1.7 返回字段过滤查询

其余代码与5.1.1一样

	   // 查询所有
        searchSourceBuilder.query(QueryBuilders.matchAllQuery());
        // 过滤字段, 类似 select name   只返回name, age字段
        String[] include = {"name","age"};
        String[] exclude = {};
        searchSourceBuilder.fetchSource(include,exclude);
        searchRequest.source(searchSourceBuilder);

5.1.8 组合查询 (多条件查询)

其余代码与5.1.1一样

		// 组合多条件查询所有
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        // 必须满足
        boolQuery.must(QueryBuilders.matchQuery("name","志豪"));
        // 或者
        boolQuery.should(QueryBuilders.matchQuery("age",18));
        // 必须不满足
        boolQuery.mustNot(QueryBuilders.matchQuery("age",199));
        searchSourceBuilder.query(boolQuery);
        searchRequest.source(searchSourceBuilder);

5.1.9 范围查询

其余代码与5.1.1一样

	 // 根据年龄范围查询
        RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery("age");
        // 大于等于
        rangeQuery.gte(10);
        // 小于等于
        rangeQuery.lte(18);
        searchSourceBuilder.query(rangeQuery);
        searchRequest.source(searchSourceBuilder);

5.2.0 模糊查询

其余代码与5.1.1一样

	   // 构建查询条件
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        // 模糊查询名称, 包含豪
        FuzzyQueryBuilder fuzzyQuery = QueryBuilders.fuzzyQuery("name", "豪");
        // 模糊策略, 默认AUTO,  选ONE, 多个一个不符合的字段都能返回
        fuzzyQuery.fuzziness(Fuzziness.ONE);
        searchSourceBuilder.query(fuzzyQuery);
        searchRequest.source(searchSourceBuilder);

5.2.1 聚合查询与分组查询

其余代码与5.1.1一样

keyword字段为关键字字段,通常搜索keyword是按照整体搜索,所以创建keyword字段的索引时是不进行分词的,比如:邮政编码、手机号码、身份证等。keyword字段通常 用于过虑、排序、聚合等 ,

如果出现了异常, 参考这里 或者 这里

最大值

		// 聚合查询- max最大值, min最小, avg平均 sum求和 count统计
        searchSourceBuilder.aggregation(AggregationBuilders.max("maxAge").field("age"));
        searchRequest.source(searchSourceBuilder);
		// 执行查询
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        // 获取结果
        SearchHits hits = searchResponse.getHits();
        // 解析获取聚合函数结果
        Map<String, Aggregation> asMap = searchResponse.getAggregations().asMap();
        // ParsedMin等等, 需要注意强转异常
        ParsedMax maxAge = (ParsedMax) asMap.get("maxAge");
        log.info("ES响应的聚合数据:{}", maxAge.getValue());

分组查询

		// 分组查询
        searchSourceBuilder.aggregation(AggregationBuilders.terms("address_groupby")
                .field("address"));
        searchRequest.source(searchSourceBuilder);

5.2.2 高亮查询

@Test
    public void queryOperate() throws IOException {
        // 高级查询
        SearchRequest searchRequest = new SearchRequest();
        // 查询那个索引下的文档数据
        searchRequest.indices("my_from_java");
        // 构建查询条件
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        // 高亮查询
        searchSourceBuilder.query(QueryBuilders.matchQuery("name","志豪"));
        // 设置高亮字段
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        // 设置标签前缀
        highlightBuilder.preTags("<font color='red'>");
        // 设置标签后缀
        highlightBuilder.postTags("</font>");
        // 设置高亮字段
        highlightBuilder.field("name");
        searchSourceBuilder.highlighter(highlightBuilder);
        searchRequest.source(searchSourceBuilder);
        // 执行查询
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        // 获取结果
        SearchHits hits = searchResponse.getHits();
        for (SearchHit hit : hits.getHits()) {
            log.info("ES响应的每条文档数据:{}", hit.getSourceAsString());
            //打印高亮结果
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            System.out.println(highlightFields);
        }
        log.info("ES响应的总记录数据:{}", hits.getTotalHits());
        log.info("ES响应的耗时数据:{}", searchResponse.getTook());
    }

1

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐