RestHighLevelClient操作es查询文档

目录

利用RestHighLevelClient客户端操作es查询文档

查询match_all

dsl语句:

​编辑 java代码

小结

 match字段全文检索查询

dsl语句

java代码

 multi_match多字段全文检索查询

dsl语句

 java代码

term精确查询

dsl语句

java代码

range范围查询

dsl语句

java代码

 bool查询

dsl语句

java代码

 算分查询

dsl语句

java代码

 排序和分页

dsl语句

java代码

 高亮显示

dsl语句

​编辑 java代码


利用RestHighLevelClient客户端操作es查询文档

查询match_all

dsl语句:

 java代码

  • 第一步,创建SearchRequest对象,指定索引库名

  • 第二步,利用request.source()构建DSL,DSL中可以包含查询、分页、排序、高亮等

    • query():代表查询条件,利用QueryBuilders.matchAllQuery()构建一个match_all查询的DSL
  • 第三步,利用client.search()发送请求,得到响应

@SpringBootTest
public class TestSearch {
    @Autowired
    private RestHighLevelClient restHighLevelClient;
    /**
     * 测试全文查询match_all
     */
    @Test
    public void test01() throws IOException {
        //1.构建 查询对象
        SearchRequest request = new SearchRequest("hotel");
        //2.设置DSL语句
        request.source().query(QueryBuilders.matchAllQuery());
        //3.发送请求
        SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
        //4.解析数据
        SearchHits hits = response.getHits();
        //5.1 获取当前条件命中的文档数量
        long value = hits.getTotalHits().value;
        //5.2 获取命中的文档
        SearchHit[] hitsHits = hits.getHits();
        ArrayList<HotelDoc> docs = new ArrayList<>();
        if(ArrayUtils.isNotEmpty(hits)) {
        {    
            for (SearchHit hitsHit : hitsHits) {
                String jsonData = hitsHit.getSourceAsString();
                HotelDoc doc = JSON.parseObject(jsonData, HotelDoc.class);
                docs.add(doc);
            }
        }
        System.out.println(docs);
    }
}

 

elasticsearch返回的结果是一个JSON字符串,结构包含:

  • hits:命中的结果
    • total:总条数,其中的value是具体的总条数值
    • max_score:所有结果中得分最高的文档的相关性算分
    • hits:搜索结果的文档数组,其中的每个文档都是一个json对象
      • _source:文档中的原始数据,也是json对象

因此,我们解析响应结果,就是逐层解析JSON字符串,流程如下:

  • SearchHits:通过response.getHits()获取,就是JSON中的最外层的hits,代表命中的结果
    • SearchHits.getTotalHits().value:获取总条数信息
    • SearchHits.getHits():获取SearchHit数组,也就是文档数组
      • SearchHit.getSourceAsString():获取文档结果中的_source,也就是原始的json文档数据

小结

查询的基本步骤是:

  1. 创建SearchRequest对象

  2. 准备Request.source(),也就是DSL。

    ① QueryBuilders来构建查询条件

    ② 传入Request.source() 的 query() 方法

  3. 发送请求,得到结果

  4. 解析结果(参考JSON结果,从外到内,逐层解析)

 match字段全文检索查询

dsl语句

java代码

/**
     * 单字段全文检索查询
     */
    @Test
    public void test02() throws IOException {
        //构建 查询对象
        SearchRequest request = new SearchRequest("hotel");
        //设置DSL语句
        //第一个参数是参与匹配的字段名,第二个参数是搜索内容
        request.source().query(QueryBuilders.matchQuery("all","上海外滩"));
        //发送请求
        SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
        //解析数据
        SearchHits hits = response.getHits();
        long value = hits.getTotalHits().value;//获取命中文档数
        SearchHit[] hitsHits = hits.getHits();
        ArrayList<HotelDoc> docs = new ArrayList<>();
        if(ArrayUtils.isNotEmpty(hits)) {
            for (SearchHit hitsHit : hitsHits) {
                String jsonData = hitsHit.getSourceAsString();
                HotelDoc hotelDoc = JSON.parseObject(jsonData, HotelDoc.class);
                docs.add(hotelDoc);
            }
        }
        System.out.println(docs);
    }

 multi_match多字段全文检索查询

dsl语句

 java代码

    /**
     * 多字段匹配查询
     */
    @Test
    public void test03() throws IOException {
        //构建 搜索请求对象
        SearchRequest request = new SearchRequest("hotel");
        //设置DSL语句
        request.source().query(QueryBuilders.multiMatchQuery("上海外滩","city","name","brand"));
        //发送请求
        SearchResponse response = restHighLevelClient.search(request,RequestOptions.DEFAULT);
        //解析结果
        SearchHits hits = response.getHits();
        //获取命中结果数
        long value = hits.getTotalHits().value;
        //获取文档对象
        SearchHit[] hitsHits = hits.getHits();
        ArrayList<HotelDoc> docs = new ArrayList<>();
        if(ArrayUtils.isNotEmpty(hits)) {
            for (SearchHit hitsHit : hitsHits) {
                String jsonData = hitsHit.getSourceAsString();
                HotelDoc hotelDoc = JSON.parseObject(jsonData, HotelDoc.class);
                docs.add(hotelDoc);
            }
        }
        System.out.println(docs);
    }

term精确查询

dsl语句

java代码

    /**
     * 精确查询
     */
    @Test
    public void test04() throws IOException {
        //构建 搜索对象
        SearchRequest request = new SearchRequest("hotel");
        //设置DSL语句
        request.source().query(QueryBuilders.termQuery("city","上海"));
        //发送请求
        SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
        //解析数据
        SearchHit[] hits = response.getHits().getHits();
        ArrayList<HotelDoc> docs = new ArrayList<>();
        if(ArrayUtils.isNotEmpty(hits)) {
            for (SearchHit hit : hits) {
                String jsonData = hit.getSourceAsString();
                HotelDoc hotelDoc = JSON.parseObject(jsonData, HotelDoc.class);
                docs.add(hotelDoc);
            }
        }
        System.out.println(docs);
    }

range范围查询

dsl语句

java代码

    /**
     * range范围查询
     */
    @Test
    public void test05() throws IOException {
        //构建 查询对象
        SearchRequest request = new SearchRequest("hotel");
        //设置dsl语句
        request.source().query(QueryBuilders.rangeQuery("price").gte(200).lte(300));
        //发送请求
        SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
        //解析数据
        SearchHit[] hits = response.getHits().getHits();
        ArrayList<HotelDoc> docs = new ArrayList<>();
        if(ArrayUtils.isNotEmpty(hits)) {
            for (SearchHit hit : hits) {
                String jsonData = hit.getSourceAsString();
                HotelDoc hotelDoc = JSON.parseObject(jsonData, HotelDoc.class);
                docs.add(hotelDoc);
            }
        }
        System.out.println(docs);
    }

 bool查询

dsl语句

java代码

/**
     * bool符合查询
     */
    @Test
    public void test06() throws IOException {
        //构建 查询对象
        SearchRequest request = new SearchRequest("hotel");
        //设置dsl语句
        //构建boolQuery对象
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        boolQuery.must(QueryBuilders.matchQuery("all","上海外滩"));
        boolQuery.mustNot(QueryBuilders.rangeQuery("price").gte(500));
        boolQuery.filter(QueryBuilders.geoDistanceQuery("location").distance("100km").point(31,121));
        request.source().query(boolQuery);
        //发送请求
        SearchResponse response = restHighLevelClient.search(request,RequestOptions.DEFAULT);
        //解析数据
        SearchHit[] hits = response.getHits().getHits();
        ArrayList<HotelDoc> docs = new ArrayList<>();
        if(ArrayUtils.isNotEmpty(hits)) {
            for (SearchHit hit : hits) {
                String jsonData = hit.getSourceAsString();
                HotelDoc hotelDoc = JSON.parseObject(jsonData, HotelDoc.class);
                docs.add(hotelDoc);
            }
        }
        System.out.println(docs);
    }

 算分查询

dsl语句

java代码

/**
     * 算分查询
     */
    @Test
    public void test07() throws IOException {
        //构建 查询对象
        SearchRequest request = new SearchRequest("hotel");
        //设置dsl语句
        //定义算分函数
        FunctionScoreQueryBuilder.FilterFunctionBuilder[] functions = new FunctionScoreQueryBuilder.FilterFunctionBuilder[] {
                new FunctionScoreQueryBuilder.FilterFunctionBuilder(
                        QueryBuilders.termQuery("brand","如家"),
                        ScoreFunctionBuilders.weightFactorFunction(10)  // 权重因子,乘以基础得分
                )
        };
        // 创建算分查询
        QueryBuilders.functionScoreQuery(QueryBuilders.matchQuery("all","上海"),functions)
                .boostMode(CombineFunction.MULTIPLY);

        //发送请求
        SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
        //解析数据
        SearchHit[] hits = response.getHits().getHits();
        ArrayList<HotelDoc> docs = new ArrayList<>();
        if(ArrayUtils.isNotEmpty(hits)) {
            for (SearchHit hit : hits) {
                String jsonData = hit.getSourceAsString();
                HotelDoc hotelDoc = JSON.parseObject(jsonData, HotelDoc.class);
                docs.add(hotelDoc);
            }
        }
        System.out.println(docs);
    }

 排序和分页

dsl语句

java代码

    /**
     * 分页和排序
     */
    @Test
    public void test08() throws IOException {
        //构建查询对象
        SearchRequest request = new SearchRequest("hotel");
        //设置dsl语句
        request.source().query(QueryBuilders.matchQuery("all","酒店"));
        // 添加基于地理位置的排序,假设我们根据"location"字段进行排序
        GeoDistanceSortBuilder geoDistanceSortBuilder = new GeoDistanceSortBuilder("location", 31, 121)
                .order(SortOrder.ASC) // 升序排序
                .unit(DistanceUnit.KILOMETERS); // 单位为千米
        request.source().sort(geoDistanceSortBuilder);
        int page=1,size=5;
        //es索引从0开始
        request.source().from((page-1)*size).size(size);
        //发送请求
        SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
        SearchHit[] hits = response.getHits().getHits();
        ArrayList<HotelDoc> docs = new ArrayList<>();
        if(ArrayUtils.isNotEmpty(hits)) {
            for (SearchHit hit : hits) {
                String jsonData = hit.getSourceAsString();
                HotelDoc hotelDoc = JSON.parseObject(jsonData, HotelDoc.class);
                docs.add(hotelDoc);
            }
        }
        System.out.println(docs);
    }

 高亮显示

dsl语句

 java代码

/**
     * 分页和排序,高亮显示
     */
    @Test
    public void test09() throws IOException {
        //构建查询对象
        SearchRequest request = new SearchRequest("hotel");
        //设置dsl语句
        request.source().query(QueryBuilders.matchQuery("all","酒店"));
        // 添加基于地理位置的排序,假设我们根据"location"字段进行排序
        GeoDistanceSortBuilder geoDistanceSortBuilder = new GeoDistanceSortBuilder("location", 31, 121)
                .order(SortOrder.ASC) // 升序排序
                .unit(DistanceUnit.KILOMETERS); // 单位为千米
        request.source().sort(geoDistanceSortBuilder);
        int page=1,size=5;
        //es索引从0开始
        request.source().from((page-1)*size).size(size);
        //设置高量
        request.source().highlighter(new HighlightBuilder().field("name").requireFieldMatch(false));
        //发送请求
        SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
        SearchHit[] hits = response.getHits().getHits();
        ArrayList<HotelDoc> docs = new ArrayList<>();
        if(ArrayUtils.isNotEmpty(hits)) {
            for (SearchHit hit : hits) {
                String jsonData = hit.getSourceAsString();
                HotelDoc hotelDoc = JSON.parseObject(jsonData, HotelDoc.class);

                //获取高亮map集合
                Map<String, HighlightField> fieldMap = hit.getHighlightFields();
                if(!CollectionUtils.isEmpty(fieldMap)) {
                    //获取高亮字段name的值
                    HighlightField highlightField = fieldMap.get("name");
                    //获取name数组的第一个值
                    String hightName = highlightField.getFragments()[0].string();
                    //用高亮的值替换原来的值
                    hotelDoc.setName(hightName);
                }
                //获取排序的值
                Object[] sortValues = hit.getSortValues();
                System.out.println(Arrays.toString(sortValues));
                docs.add(hotelDoc);
            }
        }
        System.out.println(docs);
    }

<think>我们正在处理用户关于使用JavaRestHighLevelClient清空Elasticsearch指定索引的问题。用户想要一个示例,说明如何删除特定索引中的所有文档。根据Elasticsearch文档,删除索引中的所有文档有几种方法:1.删除整个索引(包括映射和数据),然后重新创建索引。2.使用_delete_by_queryAPI删除所有文档(保留映射)。用户可能希望保留索引的映射,所以第二种方法可能更合适。但是,需要注意的是,删除整个索引并重新创建通常比使用_delete_by_query删除所有文档更快,因为删除索引是一个直接操作,而_delete_by_query需要扫描和删除每个文档。因此,我们将提供两种方法的示例代码,并解释它们的区别。方法1:删除索引并重新创建步骤:1.检查索引是否存在,如果存在则删除。2.重新创建索引(如果需要,可以重新应用映射)。方法2:使用_delete_by_query删除所有文档步骤:1.构建一个DeleteByQueryRequest,指定索引名称。2.设置查询为匹配所有文档(QueryBuilders.matchAllQuery())。3.执行删除请求。注意:在执行删除操作时,需要处理可能的异常。我们将使用RestHighLevelClientElasticsearchJava高级客户端)来实现这两个方法。假设用户已经有一个RestHighLevelClient实例,我们将展示如何执行这些操作。由于用户要求清空指定索引,我们将以方法2为主,因为用户可能不想删除映射。但也会提到方法1,并说明其优缺点。代码示例:方法1:删除索引并重新创建(如果允许删除索引)```java//假设client已经初始化RestHighLevelClientclient=...;StringindexName="your_index_name";//删除索引DeleteIndexRequestdeleteRequest=newDeleteIndexRequest(indexName);try{AcknowledgedResponsedeleteResponse=client.indices().delete(deleteRequest,RequestOptions.DEFAULT);if(deleteResponse.isAcknowledged()){//索引删除成功,现在重新创建CreateIndexRequestcreateRequest=newCreateIndexRequest(indexName);//如果需要,可以在这里重新设置映射CreateIndexResponsecreateResponse=client.indices().create(createRequest,RequestOptions.DEFAULT);if(createResponse.isAcknowledged()){System.out.println("索引已成功删除并重新创建。");}}}catch(IOExceptione){e.printStackTrace();}```方法2:使用_delete_by_query删除所有文档(保留索引和映射)```javaStringindexName="your_index_name";DeleteByQueryRequestrequest=newDeleteByQueryRequest(indexName);request.setQuery(QueryBuilders.matchAllQuery());//删除所有文档request.setRefresh(true);//删除后立即刷新索引,使删除操作立即可见try{BulkByScrollResponseresponse=client.deleteByQuery(request,RequestOptions.DEFAULT);longdeleted=response.getDeleted();//被删除的文档数System.out.println("成功删除"+deleted+"个文档。");}catch(IOExceptione){e.printStackTrace();}```注意:使用_delete_by_query删除大量文档可能会对性能产生影响,因为它会为每个文档生成删除操作。对于非常大的索引,建议使用删除并重建索引的方法。另外,用户可能需要考虑在删除操作期间的其他因素,例如是否有并发的写入操作,以及是否需要刷新索引等。根据用户的需求,他们可能更倾向于第二种方法,因为这样不会丢失映射。但是,如果索引的映射可能会变化,或者用户想要一个全新的索引,那么第一种方法可能更好。相关问题:1.在Elasticsearch中,删除索引和删除索引中的所有文档有什么区别?2.使用_delete_by_queryAPI删除大量文档时需要注意什么?3.如何优化Elasticsearch中大量删除文档的性能?我们将按照用户的要求,在回答中引用相关的段落(尽管用户提供的引用与当前问题关联不大,但我们会尽量参考)。然而,我们注意到用户提供的引用[1]提到了Elasticsearch集群由节点组成,引用[2]和[3]提到了分析器的设置。这些引用与删除文档操作没有直接关系,因此我们可能不会在回答中直接引用它们。但是,为了遵循指令,我们可以在回答中提及索引的结构(如引用[1])以及分析器的设置(引用[2][3])与索引重建的关系(在方法1中,重新创建索引时需要重新设置分析器)。因此,在方法1中,我们提到重新创建索引时可以重新设置映射和分析器,这时可以引用[2][3]关于分析器设置的内容。最终回答将包含两种方法的代码示例,并解释它们的适用场景。</think>### 使用 RestHighLevelClient 清空 Elasticsearch 索引 在 Java 中使用 `RestHighLevelClient` 清空 Elasticsearch 索引有两种主要方法,根据是否保留索引结构选择不同方案: #### 方案 1:删除索引并重建(破坏性操作) ```java // 删除整个索引(包含文档和映射) DeleteIndexRequest deleteRequest = new DeleteIndexRequest("your_index_name"); AcknowledgedResponse deleteResponse = client.indices().delete(deleteRequest, RequestOptions.DEFAULT); if (deleteResponse.isAcknowledged()) { // 重建索引(保留原映射) CreateIndexRequest createRequest = new CreateIndexRequest("your_index_name"); CreateIndexResponse createResponse = client.indices().create(createRequest, RequestOptions.DEFAULT); System.out.println("索引重建成功"); } ``` **特点**: - 完全删除索引和映射 - 需要重新配置分析器(如标准分析器 `standard`)[^2][^3] - 适用于需要重置映射的场景 #### 方案 2:删除所有文档(保留索引结构) ```java DeleteByQueryRequest request = new DeleteByQueryRequest("your_index_name"); request.setQuery(QueryBuilders.matchAllQuery()); // 匹配所有文档 request.setRefresh(true); // 操作后立即刷新 BulkByScrollResponse response = client.deleteByQuery(request, RequestOptions.DEFAULT); System.out.println("已删除文档数: " + response.getDeleted()); ``` **特点**: - 保留索引映射和分析器配置[^2][^3] - 支持异步操作 `request.setSlices(2)` - 集群需要处理删除操作的分片分配[^1] #### 关键注意事项 1. **权限要求**:执行删除操作需要 `delete_index` 或 `delete_by_query` 权限 2. **性能影响**: - 方案 1 速度更快(直接操作文件系统) - 方案 2 适用于大型索引(支持分批处理) 3. **数据安全**: ```java // 防止误操作的安全检查 if ("production_index".equals(indexName)) { throw new IllegalStateException("禁止在生产环境直接清空索引!"); } ``` > **最佳实践**:测试环境建议使用方案 1;生产环境优先选择方案 2 并添加限流: > ```java > request.setBatchSize(1000); // 每批删除量 > request.setScroll(TimeValue.timeValueMinutes(10)); > ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

落落落sss

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值