Elasticsearch-RestHighLevelClient基础操作

该篇文章参考下面博主文章
Java中ElasticSearch的各种查询(普通,模糊,前缀,高亮,聚合,范围)

【es】java使用es中三种查询用法from size、search after、scroll

一、索引

1、创建索引

 @Autowired
 private RestHighLevelClient restHighLevelClient;//es高级客户端
    /**
     * 创建索引
     *
     * @throws IOException
     */
    @Test
    void createIdx() throws IOException {
    
    

        String idx = "user_idx";//索引名称

        GetIndexRequest request = new GetIndexRequest(idx);

        boolean exists = restHighLevelClient.indices().exists(request, RequestOptions.DEFAULT);

        //判断索引是否存在
        if (!exists) {
    
    

            System.out.println(idx + "索引不存在");
            // 创建索引的请求
            CreateIndexRequest createIndexRequest = new CreateIndexRequest(idx);
            // client执行请求
            CreateIndexResponse response = restHighLevelClient.indices().create(createIndexRequest, RequestOptions.DEFAULT);
            System.out.println(idx + "索引是否创建成功:" + response.isAcknowledged());

        } else {
    
    
            System.out.println(idx + "索引存在");
        }
    }

2、定义索引结构

    /**
     * 更新索引结构
     * @throws IOException
     */
    @Test
    void updateIdxMappings() throws IOException {
    
    

        String idx = "user_idx";//你已经创建好的索引名称

        PutMappingRequest putMappingRequest = new PutMappingRequest(idx);

        //构建索引结构
        putMappingRequest.source("{\n" +
                "    \"properties\": {\n" +
                "      \"userId\":{\n" +
                "        \"type\": \"long\"\n" +
                "      },\n" +
                "      \"age\":{\n" +
                "        \"type\": \"integer\"\n" +
                "      },\n" +
                "      \"userName\":{\n" +
                "        \"type\": \"keyword\"\n" +
                "      },\n" +
                "      \"content\":{\n" +
                "        \"type\": \"text\"\n" +
                "      }\n" +
                "      }\n" +
                "    }\n" +
                "  }\n", XContentType.JSON);

        //创建索引结构
        AcknowledgedResponse acknowledgedResponse = restHighLevelClient.indices().putMapping(putMappingRequest, RequestOptions.DEFAULT);

        System.out.println("mapping是否创建成功:"+acknowledgedResponse.isAcknowledged());

        //获取索引结构
        if(acknowledgedResponse.isAcknowledged()){
    
    
            //构建请求
            GetMappingsRequest getMappingsRequest = new GetMappingsRequest().indices(idx);
            //使用RestHighLevelClient发起请求
            GetMappingsResponse getMappingsResponse = restHighLevelClient.indices().getMapping(getMappingsRequest, RequestOptions.DEFAULT);

            MappingMetaData indexMapping = getMappingsResponse.mappings().get(idx);
            Map<String, Object> mapping = indexMapping.sourceAsMap();

            System.out.println(mapping);
        }

    }

3、查询索引结构

    /**
     * 获取索引结构
     * @throws IOException
     */
    @Test
    void getIdxMappings() throws IOException {
    
    
        //构建请求
        GetMappingsRequest request = new GetMappingsRequest().indices("user_idx");
        //使用RestHighLevelClient发起请求
        GetMappingsResponse response = restHighLevelClient.indices().getMapping(request, RequestOptions.DEFAULT);

        MappingMetaData indexMapping = response.mappings().get("user_idx");
        Map<String, Object> mapping = indexMapping.sourceAsMap();

        System.out.println(mapping);

    }

4、删除索引

删除索引会把索引中已经创建好的数据也删除,就好像我们在mysql中删除库,会把库的数据也删除掉一样。

    /**
     * 删除索引
     *
     * @throws IOException
     */
    @Test
    void delteIdx() throws IOException {
    
    

        String idx = "user_idx";

        GetIndexRequest request = new GetIndexRequest(idx);
        boolean exists = restHighLevelClient.indices().exists(request, RequestOptions.DEFAULT);

        if (exists) {
    
    
            //创建删除索引请求
            DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest(idx);
            //执行
            AcknowledgedResponse delete = restHighLevelClient.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT);
            //得到相应
            boolean acknowledged = delete.isAcknowledged();
            System.out.println(idx + "是否删除索引成功:" + acknowledged);

        } else {
    
    
            System.out.println(idx + "索引不存在");
        }

    }

5、关闭索引

类似关闭数据库

    /**
     * 关闭索引
     *
     * @throws IOException
     */
    @Test
    void stopIdx() throws IOException {
    
    

        String idx = "nan_index_5";

        GetIndexRequest request = new GetIndexRequest(idx);
        boolean exists = restHighLevelClient.indices().exists(request, RequestOptions.DEFAULT);

        if (exists) {
    
    

            CloseIndexRequest closeIndexRequest = new CloseIndexRequest(idx);

            AcknowledgedResponse close = restHighLevelClient.indices().close(closeIndexRequest, RequestOptions.DEFAULT);

            boolean acknowledged = close.isAcknowledged();

            System.out.println(idx + "索引是否关闭:" + acknowledged);

        } else {
    
    
            System.out.println(idx + "索引不存在");
        }


    }

6、启动索引

类似启动数据库

    /**
     * 启动索引
     *
     * @throws IOException
     */
    @Test
    void openIdx() throws IOException {
    
    


        String idx = "nan_index_5";

        GetIndexRequest request = new GetIndexRequest(idx);
        boolean exists = restHighLevelClient.indices().exists(request, RequestOptions.DEFAULT);

        if (exists) {
    
    


            OpenIndexRequest openIndexRequest = new OpenIndexRequest(idx);

            OpenIndexResponse open = restHighLevelClient.indices().open(openIndexRequest, RequestOptions.DEFAULT);

            boolean acknowledged = open.isAcknowledged();
            System.out.println(idx + "索引是否启动:" + acknowledged);

        } else {
    
    
            System.out.println(idx + "索引不存在");
        }
    }

二、文档

1、定义实体类


import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

import java.io.Serializable;


@Data
@NoArgsConstructor //无参构造函数
@AllArgsConstructor//有参构造(全字段)
@Accessors(chain = true)//链式; 存取器。通过该注解可以控制getter和setter方法的形式。
public class UserStrDto implements Serializable {
    
    

    private static final long serialVersionUID = 1L;

    private String userId;//主键

    private Integer age;

    private String userName;

    private String content;


}

2、插入/更新文档

如果是更新文档,不传的值es会设为空,谨慎操作

/**
     * 插入/更新文档
     * @throws IOException
     */
    @Test
    public void updateAllDoc() throws IOException {
    
    


        //String idStr = "1680826880220434434";//更新已插入的文档
        String idStr = IdWorker.getIdStr();//插入文档

        UserStrDto userDto = new UserStrDto();

        userDto.setUserId(idStr)
                .setUserName("小尾")
                .setAge(45)
                .setContent("我是小尾");

        String userStrJson = JSON.toJSONString(userDto);
        System.out.println(userStrJson);

        IndexRequest indexRequest = new IndexRequest("user_idx").id(idStr);
        indexRequest.source(userStrJson, XContentType.JSON);
        IndexResponse index = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
        System.out.println(index.status());//CREATED=新增成功

    }

3、删除文档

es推荐使用id进行删除,不建议通过查询进行删除

   /**
     * 根据id删除
     *
     * @throws IOException
     */
    @Test
    public void deleteDoc() throws IOException {
    
    
        DeleteRequest deleteRequest = new DeleteRequest("user_idx", "167977903112262861");
        DeleteResponse delete = restHighLevelClient.delete(deleteRequest, RequestOptions.DEFAULT);
        System.out.println(delete.status());
    }

4、更新文档指定字段

这里只修改传值的字段,不传的字段值不会修改,还是原样

    /**
     * 根据id更新
     *
     * @throws IOException
     */
    @Test
    public void updateDoc() throws IOException {
    
    
        UpdateRequest updateRequest = new UpdateRequest("user_idx", "1681124336241922050");
        UserStrDto userDto = new UserStrDto();
        userDto.setUserName("大黄");//仅更新指定的字段
        String userStrJson = JSON.toJSONString(userDto);
        System.out.println(userStrJson);
        updateRequest.doc(userStrJson, XContentType.JSON);
        UpdateResponse update = restHighLevelClient.update(updateRequest, RequestOptions.DEFAULT);
        System.out.println(update.status());
    }

三、分页查询

1、from+size(不推荐)

from + size是有限制的,from和size二者之和不能超过1W

@Autowired
private RestHighLevelClient restHighLevelClient;

    @Test
    void termQuery() throws IOException {
    
    

        //1. 创建Request对象
        SearchRequest request = new SearchRequest("user_idx");

        //2. 指定查询条件
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.from(0);//跳过开始的结果数,默认0   ->    (页数-1)*结果数
        builder.size(5);//结果数,默认10
        builder.query(QueryBuilders.termQuery("userName","小白"));

        request.source(builder);

        //3. 执行查询
        SearchResponse resp = restHighLevelClient.search(request, RequestOptions.DEFAULT);

        //4. 获取到_source中的数据,并展示
        for (SearchHit hit : resp.getHits().getHits()) {
    
    
            Map<String, Object> result = hit.getSourceAsMap();
            System.out.println(result);
        }
    }

2、Scroll

@Autowired
private RestHighLevelClient restHighLevelClient;
    @Test
    void scrollQuery() throws IOException {
    
    

         //1. 创建SearchRequest
        SearchRequest request = new SearchRequest("user_idx");


        //2. 指定scroll信息!
        request.scroll(TimeValue.timeValueMinutes(1L));//指定生存时间为1m,1分钟

        //3. 指定查询条件
        SearchSourceBuilder builder = new SearchSourceBuilder();
        builder.size(1);//每页4条数据
        builder.sort("age", SortOrder.DESC);//按年龄排序
        builder.fetchSource(new String[]{
    
    "userName", "age"},null);//只返回userName和age两个字段
        builder.query(QueryBuilders.matchAllQuery());

        request.source(builder);

        //4. 获取返回结果scrollId,source
        SearchResponse resp = restHighLevelClient.search(request, RequestOptions.DEFAULT);

        String scrollId = resp.getScrollId();
        System.out.println("----------首页---------"+scrollId);
        for (SearchHit hit : resp.getHits().getHits()) {
    
    
            System.out.println(hit.getSourceAsMap());
        }

        //模拟下一页
        while(true) {
    
    
            //5. 循环 - 创建SearchScrollRequest
            SearchScrollRequest scrollRequest = new SearchScrollRequest(scrollId);//根据前面得到的scorll_id去指定

            //6. 指定scrollId的生存时间!
            scrollRequest.scroll(TimeValue.timeValueMinutes(1L));

            //7. 执行查询获取返回结果
            SearchResponse scrollResp = restHighLevelClient.scroll(scrollRequest, RequestOptions.DEFAULT);

            //8. 判断是否查询到了数据,输出
            SearchHit[] hits = scrollResp.getHits().getHits();

            if(hits != null && hits.length > 0) {
    
    
                System.out.println("----------下一页---------");
                for (SearchHit hit : hits) {
    
    
                System.out.println(hit.getSourceAsMap());
                }
            }else{
    
    
                //9. 判断没有查询到数据-退出循环
                System.out.println("----------结束---------");
                break;
            }
        }

        //10. 创建CLearScrollRequest
        ClearScrollRequest clearScrollRequest = new ClearScrollRequest();

        //11. 指定ScrollId
        clearScrollRequest.addScrollId(scrollId);

        //12. 删除ScrollId
        ClearScrollResponse clearScrollResponse = restHighLevelClient.clearScroll(clearScrollRequest, RequestOptions.DEFAULT);

        //13. 输出结果
        System.out.println("删除scroll:" + clearScrollResponse.isSucceeded());




    }

3、searchAfter(推荐)

import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RegexpQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.IOException;
import java.util.Arrays;

@SpringBootTest
public class EsSearchAfterTest {
    
    


    @Autowired
    private RestHighLevelClient restHighLevelClient;

    /**
     * 首页
     * @throws IOException
     */
    @Test
    void searchAfterQuery() throws IOException {
    
    
        // 请求 es
        SearchRequest searchRequest = new SearchRequest("user_idx");

        //查询条件
        BoolQueryBuilder boolQueryBuild = QueryBuilders.boolQuery();
        QueryBuilder matchQuery = QueryBuilders.matchQuery("content", "我是小");
        boolQueryBuild.filter(matchQuery);

         // 构建请求  设置查询条件 排序条件
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.size(1)
                        .sort(SortBuilders.fieldSort("age").order(SortOrder.ASC))
                                .sort(SortBuilders.fieldSort("userName").order(SortOrder.ASC))
                                        .query(boolQueryBuild);


        searchRequest.source(searchSourceBuilder);
        SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        SearchHit[] hits = search.getHits().getHits();
        Object[] sortValue = hits[hits.length - 1].getSortValues();
        System.out.println("最后一条数据sort_id为:"+ Arrays.toString(sortValue));


        System.out.println("----------首页---------");
        for (SearchHit hit : search.getHits().getHits()) {
    
    
            //System.out.println(hit.getSourceAsMap());//map
            System.out.println(hit.getSourceAsString());//json字符
            Object[] sortValues = hit.getSortValues();
            //System.out.println(Arrays.toString(sortValues));//每条数据的sort值
        }



    }


    /**
     * 获取下一页
     * @param sortData 上一页最后一条数据的sort值
     * @throws IOException
     */
    @Test
    void nextSearchAfterQuery(Object[] sortData) throws IOException{
    
    

        // 请求 es
        SearchRequest searchRequest = new SearchRequest("user_idx");

        //查询条件
        BoolQueryBuilder boolQueryBuild = QueryBuilders.boolQuery();
        QueryBuilder matchQuery = QueryBuilders.matchQuery("content", "我是小");
        boolQueryBuild.filter(matchQuery);

        // 构建请求  设置查询条件 排序条件
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.size(1)
                .sort(SortBuilders.fieldSort("age").order(SortOrder.ASC))
                .sort(SortBuilders.fieldSort("userName").order(SortOrder.ASC))
                .query(boolQueryBuild)
                .searchAfter(sortData);//下一页的时候才加这个,放上一页最后一条数据的sort值



        searchRequest.source(searchSourceBuilder);
        SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        SearchHit[] hits = search.getHits().getHits();
        Object[] sortValue = hits[hits.length - 1].getSortValues();
        System.out.println("最后一条数据sort_id为:"+ Arrays.toString(sortValue));

        System.out.println("----------下一页---------");
        for (SearchHit hit : search.getHits().getHits()) {
    
    
            System.out.println(hit.getSourceAsString());//json字符
        }

    }




}

猜你喜欢

转载自blog.csdn.net/qq407995680/article/details/131807857