使用JavaRestClient查询文档&排序、分页、高亮

导读:本篇文章讲解 使用JavaRestClient查询文档&排序、分页、高亮,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

可以参考着“利用JavaRestClient实现文档的CRUD(从mysql数据库转移到es)”来看

http://t.csdn.cn/SP5nx

1、解析响应的方法

   private void handleResponse(SearchResponse response) {
        // 4.解析响应
        SearchHits searchHits = response.getHits();
        // 4.1.获取总条数
        long total = searchHits.getTotalHits().value;
        System.out.println("共搜索到" + total + "条数据");
        // 4.2.文档数组
        SearchHit[] hits = searchHits.getHits();
        // 4.3.遍历
        for (SearchHit hit : hits) {
            // 获取文档source
            String json = hit.getSourceAsString();
            // 反序列化
            //HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
            //System.out.println("hotelDoc = " + hotelDoc);
            System.out.println(json);
        }
    }

2、无条件查找

package cn.itcast.hotel;

import cn.itcast.hotel.pojo.HotelDoc;
import cn.itcast.hotel.service.IHotelService;
import cn.itcast.hotel.utils.HotelConstants;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpHost;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

/**
 * 酒店查询测试
 *
 * @author ning
 * @since 2022/12/5 22:45
 */

@Slf4j
@SpringBootTest
public class HotelSearchTest {

    @Autowired
    private IHotelService hotelService;

    @Test
    void testMatchAll() throws Exception {
        //初始化RestHighLevelClient:
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(HttpHost.create("http://192.168.177.132:9200"))
        );
        //创建请求
        //hotel 是查询的文档名
        SearchRequest request = new SearchRequest("hotel");
        //设置参数
        //QueryBuilders 工具类
        //matchAllQuery() 无条件查询
        request.source()
                .query(QueryBuilders.matchAllQuery());
        //执行请求
        //第一个参数:创建的请求,第二个参数:是否还有其他的选项,一般选DEFAULT
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        //解析响应
        handleResponse(response);
    }

    private void handleResponse(SearchResponse response) {
        // 4.解析响应
        SearchHits searchHits = response.getHits();
        // 4.1.获取总条数
        long total = searchHits.getTotalHits().value;
        System.out.println("共搜索到" + total + "条数据");
        // 4.2.文档数组
        SearchHit[] hits = searchHits.getHits();
        // 4.3.遍历
        for (SearchHit hit : hits) {
            // 获取文档source
            String json = hit.getSourceAsString();
            // 反序列化
            HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
            System.out.println("hotelDoc = " + hotelDoc);
        }
    }
}

使用JavaRestClient查询文档&排序、分页、高亮

 3、全文检索查询

使用JavaRestClient查询文档&排序、分页、高亮

 单字段全文检索查询:match查询

代码和上边无条件查询基本一致,只是需要把查询条件换一下

//设置参数
        //QueryBuilders 工具类
        request.source()
                .query(
                        //QueryBuilders.matchAllQuery() //无条件查询
                        QueryBuilders.matchQuery("all", "如家")//match查询(单字段全文检索查询)
                );

使用JavaRestClient查询文档&排序、分页、高亮

 使用JavaRestClient查询文档&排序、分页、高亮

  多字段全文检索查询:multi_match查询

代码和上边无条件查询基本一致,只是需要把查询条件换一下

//设置参数
        //QueryBuilders 工具类
        request.source()
                .query(
                        //QueryBuilders.matchAllQuery() //无条件查询
                        //QueryBuilders.matchQuery("all", "如家")//match查询(单字段全文检索查询)
                        QueryBuilders.multiMatchQuery("如家","name","brand","business")//multi_match查询(多字段全文检索查询)
                );

使用JavaRestClient查询文档&排序、分页、高亮

 使用JavaRestClient查询文档&排序、分页、高亮

 4、精确查询

使用JavaRestClient查询文档&排序、分页、高亮

 精确查询主要是两者:

  • term:词条精确匹配

  • range:范围查询

term:词条精确匹配

        //设置参数
        //QueryBuilders 工具类
        request.source()
                .query(
                        //QueryBuilders.matchAllQuery() //无条件查询
                        //QueryBuilders.matchQuery("all", "如家")//match查询(单字段全文检索查询)
                        //QueryBuilders.multiMatchQuery("如家","name","brand","business")//multi_match查询(多字段全文检索查询)
                        QueryBuilders.termQuery("city","北京")//词条精确匹配
                );

使用JavaRestClient查询文档&排序、分页、高亮

使用JavaRestClient查询文档&排序、分页、高亮

 range:范围查询

        //设置参数
        //QueryBuilders 工具类
        request.source()
                .query(
                        //QueryBuilders.matchAllQuery() //无条件查询
                        //QueryBuilders.matchQuery("all", "如家")//match查询(单字段全文检索查询)
                        //QueryBuilders.multiMatchQuery("如家","name","brand","business")//multi_match查询(多字段全文检索查询)
                        //QueryBuilders.termQuery("city","北京")//term:词条精确匹配
                        QueryBuilders.rangeQuery("price").gte(100).lte(200)//range:范围查询
                );

使用JavaRestClient查询文档&排序、分页、高亮

 使用JavaRestClient查询文档&排序、分页、高亮

 5、复合查询-boolean query

布尔查询是用must、must_not、filter等方式组合其它查询,代码示例如下:

使用JavaRestClient查询文档&排序、分页、高亮

 

//设置参数
        //QueryBuilders 工具类
        request.source()
                .query(
                        //QueryBuilders.matchAllQuery() //无条件查询
                        //QueryBuilders.matchQuery("all", "如家")//match查询(单字段全文检索查询)
                        //QueryBuilders.multiMatchQuery("如家","name","brand","business")//multi_match查询(多字段全文检索查询)
                        //QueryBuilders.termQuery("city","北京")//term:词条精确匹配
                        //QueryBuilders.rangeQuery("price").gte(100).lte(200)//range:范围查询
                        //boolQuery 布尔查询
                        //其中的子查询包括酒店名字为如家,并且价格在100~200之间的
                        //子查询可以有多个
                        QueryBuilders.boolQuery()
                                .must(QueryBuilders.matchQuery("name", "如家"))
                                .filter(QueryBuilders.rangeQuery("price").gte(100).lte(200))
                );

使用JavaRestClient查询文档&排序、分页、高亮

 使用JavaRestClient查询文档&排序、分页、高亮

 6、对查询结果进行排序和分页

计算分页的公式:(当前页-1)*每页显示多少条数据,可以得出要从哪一条数据开始查

//排序
        //按照价格升序
        request.source().sort("price", SortOrder.ASC);
        //分页
        //一般由前端返回分页的数据
        int pageNo = 1;//当前页
        int pageSize = 2;//每页显示多少数据
        request.source().from((pageNo-1)*pageSize).size(pageSize);

使用JavaRestClient查询文档&排序、分页、高亮

 使用JavaRestClient查询文档&排序、分页、高亮

 7、对查询结果高亮显示

高亮的代码与之前代码差异较大,有两点:

  • 查询的DSL:其中除了查询条件,还需要添加高亮条件,同样是与query同级。

  • 结果解析:结果除了要解析_source文档数据,还要解析高亮结果

7.1 高亮请求构建

高亮查询必须使用全文检索查询,并且要有搜索关键字,将来才可以对关键字高亮。

使用JavaRestClient查询文档&排序、分页、高亮

//高亮的请求
        //将酒店名中的如家两个字高亮显示,
        //HighlightBuilder 工具类
        //field 在哪个字段使用高亮显示
        //requireFieldMatch 如果查询的字段和高亮显示使用的字段比一样,需要指定为false
        //建议就算一样,也写上,不会有影响
        request.source().highlighter(
                new HighlightBuilder().field("name").requireFieldMatch(false)
        );

使用JavaRestClient查询文档&排序、分页、高亮

 7.3 高亮结果解析

高亮的结果与查询的文档结果默认是分离的,并不在一起。

因此解析高亮的代码需要额外处理:

使用JavaRestClient查询文档&排序、分页、高亮

 代码解读:

  • 第一步:从结果中获取source。hit.getSourceAsString(),这部分是非高亮结果,json字符串。还需要反序列为HotelDoc对象

  • 第二步:获取高亮结果。hit.getHighlightFields(),返回值是一个Map,key是高亮字段名称,值是HighlightField对象,代表高亮值

  • 第三步:从map中根据高亮字段名称,获取高亮字段值对象HighlightField

  • 第四步:从HighlightField中获取Fragments,并且转为字符串。这部分就是真正的高亮字符串了

  • 第五步:用高亮的结果替换HotelDoc中的非高亮结果

    private void handleResponse(SearchResponse response) {
        // 4.解析响应
        SearchHits searchHits = response.getHits();
        // 4.1.获取总条数
        long total = searchHits.getTotalHits().value;
        System.out.println("共搜索到" + total + "条数据");
        // 4.2.文档数组
        SearchHit[] hits = searchHits.getHits();
        // 4.3.遍历
        for (SearchHit hit : hits) {
            // 获取文档source
            String json = hit.getSourceAsString();
            System.out.println(json);
             反序列化
            //HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
            // 获取高亮结果
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            if (!CollectionUtils.isEmpty(highlightFields)) {
                // 根据字段名获取高亮结果
                HighlightField highlightField = highlightFields.get("name");
                if (highlightField != null && highlightField.getFragments().length > 0) {
                    // 获取高亮值
                    String name = highlightField.getFragments()[0].string();
                     覆盖非高亮结果
                    //hotelDoc.setName(name);
                    System.out.println("高亮处理后的酒店名称:" + name);
                }
            }
        }
    }

使用JavaRestClient查询文档&排序、分页、高亮

 使用JavaRestClient查询文档&排序、分页、高亮

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/65870.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!