分布式搜索引擎ElasticSearch——搜索功能

发布时间:2024年01月15日

分布式搜索引擎ElasticSearch——搜索功能


在这里插入图片描述

DSL查询文档

在这里插入图片描述

DSL查询分类

在这里插入图片描述
DSL官方文档
在这里插入图片描述
在这里插入图片描述

全文检索查询

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

精确查询

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

地理查询

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

复合查询

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Function Score Query

在这里插入图片描述
function score query
在这里插入图片描述
在这里插入图片描述

Boolean Query

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

搜索结果处理

在这里插入图片描述

排序在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

分页

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
官方文档
在这里插入图片描述

高亮

在这里插入图片描述
在这里插入图片描述

RestClient查询文档

在这里插入图片描述

快速入门

在这里插入图片描述

在这里插入图片描述


public class HotelSearchTest {
    private RestHighLevelClient client;

    @Test
    void testMatchAll() throws IOException {
        // 1. 准备Request
        SearchRequest request = new SearchRequest("hotel");
        // 2. 准备DSL
        request.source().query(QueryBuilders.matchAllQuery());
        // 3. 发送请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);

        // 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(response);
    }

    @BeforeEach
    void setUp(){
        this.client = new RestHighLevelClient(RestClient.builder(
                HttpHost.create("http://192.168.10.88:9200")
        ));
    }

    @AfterEach
    void tearDown() throws IOException {
        this.client.close();
    }
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

match,term,range,bool查询

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  // 全文检索查询
    @Test
    void testMatch() throws IOException {
        // 1. 准备Request
        SearchRequest request = new SearchRequest("hotel");
        // 2. 准备DSL
        request.source().query(QueryBuilders.matchQuery("all","皇冠"));
        // 3. 发送请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);

        handleResponse(response);
        System.out.println(response);
    }

    // bool查询
    @Test
    void testBool() throws IOException {
        // 1. 准备Request
        SearchRequest request = new SearchRequest("hotel");
        // 2. 准备DSL
        // 2.1 准备BooleanQuery
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        // 2.2 添加term
        boolQuery.must(QueryBuilders.termQuery("city","杭州"));
        // 2.3 添加range
        boolQuery.filter(QueryBuilders.rangeQuery("price").lte(250));

        request.source().query(boolQuery);
        // 3. 发送请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);

        handleResponse(response);
        System.out.println(response);
    }

    // 抽取解析的代码
    private static 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);
        }
    }

在这里插入图片描述

排序和分页

在这里插入图片描述

// 排序和分页
    @Test
    void testPageAndSort() throws IOException {
        // 页码。每页大小
        int page  = 2, size  = 5;
        // 1. 准备Request
        SearchRequest request = new SearchRequest("hotel");
        // 2. 准备DSL
        // 2.1 query
        request.source().query(QueryBuilders.matchAllQuery());
        // 2.2 配许sort
        request.source().sort("price", SortOrder.ASC);
        // 2.3 分页from, size
        request.source().from((page-1)*size).size(5);
        // 3. 发送请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        // 4. 解析响应
        handleResponse(response);
    }

高亮显示

在这里插入图片描述

 // 高亮
    @Test
    void testHighlight() throws IOException {
        // 1. 准备Request
        SearchRequest request = new SearchRequest("hotel");
        // 2. 准备DSL
        // 2.1 query
        request.source().query(QueryBuilders.matchQuery("all","如家"));
        // 2.2 高亮
        request.source().highlighter(new HighlightBuilder().field("name").requireFieldMatch(false));
        // 3. 发送请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        // 4. 解析响应
        handleResponse(response);
    }

在这里插入图片描述
就是在前面抽取的解析代码中进一步添加关于高亮的解析部分,因为highlight和source是同级目录的,所以采用的方法类似。

  // 抽取解析的代码
    private static 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);
            // 获取高亮结果
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            if(!CollectionUtils.isEmpty(highlightFields)){
                // 根据字段名获取高亮结果
                HighlightField highlightField = highlightFields.get("name");
                if(highlightField != null){
                    //  获取高亮值
                    String name = highlightField.getFragments()[0].string();
                    // 覆盖非高亮结果
                    hotelDoc.setName(name);
                }
            }
            System.out.println("hotelDoc = " + hotelDoc);
        }
    }

在这里插入图片描述

黑马旅游案例

在这里插入图片描述

基本的搜索和分页

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

@RestController
@RequestMapping("/hotel")
public class HotelController {

    @Autowired
    private IHotelService hotelService;

    @PostMapping("/list")
    public PageResult search(@RequestBody RequestParams params){
        return hotelService.search(params);
    }
}

在这里插入图片描述

@Service
public class HotelService extends ServiceImpl<HotelMapper, Hotel> implements IHotelService {

    @Autowired
    private RestHighLevelClient client;

    @Override
    public PageResult search(RequestParams params) {
        try {// 1. 准备Request
            SearchRequest request = new SearchRequest("hotel");
            // 2. 准备DSL
            // 2.1 query
            String key = params.getKey();
            if (key == null || "".equals(key)) {
                request.source().query(QueryBuilders.matchAllQuery());
            } else {
                request.source().query(QueryBuilders.matchQuery("all", key));
            }
            // 2.2 分页
            int page = params.getPage();
            int size = params.getSize();
            request.source().from((page - 1) * size).size(size);
            // 3. 发送请求
            SearchResponse response = client.search(request, RequestOptions.DEFAULT);
            // 4. 解析响应
            return handleResponse(response);
        }catch (IOException e){
            throw new RuntimeException(e);
        }
    }


    // 抽取解析的代码
    private PageResult handleResponse(SearchResponse response) {
        // 4. 解析响应
        SearchHits searchHits = response.getHits();
        // 4.1 获取总条数
        long total = searchHits.getTotalHits().value;
        // 4.2 文档数组
        SearchHit[] hits = searchHits.getHits();

        // 4.3 遍历
        List<HotelDoc> hotels = new ArrayList<>();
        for (SearchHit hit : hits) {
            // 获取文档source
            String json = hit.getSourceAsString();
            // 反序列化
            HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
            hotels.add(hotelDoc);
        }
        // 4.4 封装返回
        return new PageResult(total,hotels);
    }


}

条件过滤

在这里插入图片描述在这里插入图片描述

在这里插入图片描述

@Override
    public PageResult search(RequestParams params) {
        try {// 1. 准备Request
            SearchRequest request = new SearchRequest("hotel");
            // 2. 准备DSL
            // 2.1 query
            // 构建BooleanQuery

            buildBasicQuery(params, request);

            // 2.2 分页
            int page = params.getPage();
            int size = params.getSize();
            request.source().from((page - 1) * size).size(size);
            // 3. 发送请求
            SearchResponse response = client.search(request, RequestOptions.DEFAULT);
            // 4. 解析响应
            return handleResponse(response);
        }catch (IOException e){
            throw new RuntimeException(e);
        }
    }

    private static void buildBasicQuery(RequestParams params, SearchRequest request) {
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        // 关键字搜索
        String key = params.getKey();
        if (key == null || "".equals(key)) {
            boolQuery.must(QueryBuilders.matchAllQuery());
        } else {
            boolQuery.must(QueryBuilders.matchQuery("all", key));
        }
        // 条件过滤
        // 城市
        if(params.getCity() !=  null && !"".equals(params.getCity())){
            boolQuery.filter(QueryBuilders.termQuery("city", params.getCity()));
        }
        // 品牌
        if(params.getBrand() !=  null && !"".equals(params.getBrand())){
            boolQuery.filter(QueryBuilders.termQuery("brand", params.getBrand()));
        }
        // 星级
        if(params.getStarName() !=  null && !"".equals(params.getStarName())){
            boolQuery.filter(QueryBuilders.termQuery("starName", params.getStarName()));
        }
        // 价格——范围过滤
        if(params.getMinPrice() != null && params.getMaxPrice() != null){
            boolQuery.filter(QueryBuilders.rangeQuery("price").gte(params.getMinPrice()).lte(params.getMaxPrice()));
        }

        request.source().query(boolQuery);
    }

找周边的酒店

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

广告置顶

在这里插入图片描述
在这里插入图片描述

        // 2.  算分控制
        FunctionScoreQueryBuilder functionScoreQuery =
                QueryBuilders.functionScoreQuery(
                        // 原始查询,相关性算分的查询
                        boolQuery,
                        // function score的数组
                        new FunctionScoreQueryBuilder.FilterFunctionBuilder[]{
                                //  其中的一个function score元素
                                new FunctionScoreQueryBuilder.FilterFunctionBuilder(
                                        // 过滤条件
                                        QueryBuilders.termQuery("isAD",true),
                                        // 算分函数
                                        ScoreFunctionBuilders.weightFactorFunction(10)
                                )
                        });
文章来源:https://blog.csdn.net/shall_zhao/article/details/135585070
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。