• 微服务技术栈SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式(五):分布式搜索 ES-中



    一、DSL查询文档

    在这里插入图片描述

    1.1 简单查询

    # 1. DSL查询
    # 1.1 查询所有
    
    GET /hotel/_search
    {
      "query": {
        "match_all": {}
      }
    }
    
    # 1.2 全文检索查询:对用户输入的内容分词后查询,常用于搜索框查询
    # 1)match查询 :all字段是在创建hotel索引库时创建的,里面包括brand name busiess字段(copy to)
    # 例子:查询hotel中brand、name、businiss中有"外滩"二字的文档
    GET /hotel/_search
    {
      "query": {
        "match": {
          "all": "外滩"
        }
      }
    }
    # 2)muiti_match查询:效果和上面一样
    # 例子:查询hotel中brand、name、businiss中有"外滩如家"四字的文档
    GET /hotel/_search
    {
      "query": {
        "multi_match": {
          "query": "外滩如家",
          "fields": ["brand","name","business"]
        }
      }
    }
    # 3)match与multi_match的区别在于:match是单字段查询;而multi_match是多字段查询,字段越多性能越差;建议用copy to将多个字段拷到一个字段用match查询
    
    
    # 1.3 精确查询:一般查找类型为keyword、boolean、数值、日期等字段,不分词
    # 1)term:根据词条的精确值查询
    # 例子:查询hotel中city="上海"的文档
    GET /hotel/_search
    {
      "query": {
        "term": {
          "city": {
            "value": "上海"
          }
        }
      }
    }
    # 2)range:根据值的范围查询
    # 例子:查询price在(1000,2000]的文档
    GET /hotel/_search
    {
      "query": {
        "range": {
          "price": {
            "gt": 1108,
            "lte": 2000
          }
        }
      }
    }
    
    # 1.4 经纬度查询
    # 1)geo_bounding_box:查询geo_point值落在某个矩形范围的所有文档
    # 例子:查询hotel中location两个经纬度点矩形范围内内的文档
    GET /hotel/_search
    {
      "query": {
        "geo_bounding_box": {
          "location": {
            "top_left": {
              "lat": 31.1,
              "lon": 121.5
            },
            "bottom_right": {
              "lat": 30.9,
              "lon": 121.7
            }
          }
        }
      }
    }
    
    # 2)geo_distance:查询到指定中心点小于某个距离值的所有文档
    # 例子:查询(31.21,121.5)范围内5km的的文档
    GET /hotel/_search
    {
      "query": {
        "geo_distance": {
          "distance": "5km",
          "location": "31.21, 121.5"
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94

    1.2 复合查询

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

    # 1.5 复合查询
    # 1function socre:算分函数查询,可以控制文档相关性算分,控制文档的排名
    # 例:在all为"外滩"的查询中将"如家"这个品牌的酒店排名靠前一些
    GET /hotel/_search
    {
      "query": {
        "function_score": {
          "query": {
            "match": {
              "all": "外滩"
            }
          },
          "functions": [
            {
              "filter": {
                "term": {
                  "brand": "如家"
                }
              },
              "weight": 10
            }
          ],
          "boost_mode": "sum"
        }
      }
    }
    
    # 2)布尔查询:组合多个子查询
    # must:必须匹配每个子查询,相当于“与”
    # should:选择性匹配子查询,相当于“或”
    # must_not:必须不匹配【不参与算分】,相当于“非”
    # filter:必须匹配【不参与算法】
    
    # 例:查询name包含"如家",价格不高于400,坐标(31.21,121.5)范围内10km的hotel
    # 下面代码中,如果将price和location放入must中会参与算分,为了节省性能,一般放在must_not或者filter中
    GET /hotel/_search
    {
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "name": "如家"
              }
            }
          ],
          "must_not": [
            {
              "range": {
                "price": {
                  "gt": 400
                }
              }
            }
          ],
          "filter": [
            {
              "geo_distance": {
                "distance": "10km",
                "location": {
                  "lat": 31.21,
                  "lon": 121.5
                }
              }
            }
          ]
        }
      }
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71

    二、搜索结果处理

    深度分页问题
    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    # 2. 搜索结果处理
    # 2.1 排序:es默认根据算分排序。可以用来排序的字段有:keyword、数值、坐标、日期
    # 例1:对hotel数据按用户评价score降序,相同评价按价格price升序
    GET /hotel/_search
    {
      "query": {
        "match_all": {}
      },
      "sort": [
        {
          "score": "desc"
        },
        {
          "price": "asc"
        }
      ]
    }
    
    # 例2:对hotel数据按你的坐标位置(115.450059,38.866053)距离升序排序
    # 获取经纬度的方式:https://lbs.amap.com/demo/jsapi-v2/example/map/click-to-get-lnglat/
    GET /hotel/_search
    {
      "query": {
        "match_all": {}
      },
      "sort": [
        {
          "_geo_distance": {
            "location": {
              "lat": 38.866053,
              "lon": 115.45005
            },
            "order": "asc",
            "unit": "km"
          }
        }
      ]
    }
    
    
    
    # 2.2 分页:es默认返回top10的数据,想要查询更多需要设置
    # from表示分页开始位置,默认为0;size表示期望获取文档数
    
    GET /hotel/_search
    {
      "query": {
        "match_all": {}
      },
      "from": 5,
      "size": 1,
      "sort": [
        {
          "price": "asc"
        }
      ]
    }
    
    # 2.3 高亮:将搜索结果的搜索关键字突出显示
    # 原理:将搜索结果的关键字用标签标记出来,在页面中给标签添加css样式
    # 注意:默认情况下ES搜索字段必须与高亮字段保持一致,而下面搜索字段为all,高亮字段为name,虽然all包括name,但是需要设置require_field_match=false
    GET /hotel/_search
    {
      "query": {
        "match": {
          "all": "如家"
        }
      },
      "highlight": {
        "fields": {
          "name": {
            "require_field_match": "false", 
            "pre_tags": "",
            "post_tags": ""
          }
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78

    在这里插入图片描述

    三、RestClient演示 查询与结果分析

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    @SpringBootTest
    class HotelSearchTest {
    
        private RestHighLevelClient client;
    
        @BeforeEach
        void setUp() {
            client = new RestHighLevelClient(RestClient.builder(
                    HttpHost.create("http://192.168.1.101:9200")
            ));
        }
    
        @AfterEach
        void tearDown() throws IOException {
            client.close();
        }
    
        /**
         * 解析json文档
         */
        private void handleResponse(SearchResponse response) {
            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) {
                // 4.4.获取source
                String json = hit.getSourceAsString();
                // 4.5.反序列化,非高亮的
                HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
                // 4.6.处理高亮结果
                // 1)获取高亮map
                Map<String, HighlightField> map = hit.getHighlightFields();
                // 2)根据字段名,获取高亮结果
                HighlightField highlightField = map.get("name");
                // 3)获取高亮结果字符串数组中的第1个元素
                String hName = highlightField.getFragments()[0].toString();
                // 4)把高亮结果放到HotelDoc中
                hotelDoc.setName(hName);
                // 4.7.打印
                System.out.println(hotelDoc);
                System.out.println(json);
            }
        }
    
        /**
         * 查询所有文档
         */
        @Test
        void testMatchAll() throws IOException {
            // 1.准备request
            SearchRequest request = new SearchRequest("hotel");
            // 2.准备请求参数
            request.source().query(QueryBuilders.matchAllQuery());
            // 3.发送请求,得到响应
            SearchResponse response = client.search(request, RequestOptions.DEFAULT);
            // 4.结果解析
            handleResponse(response);
        }
    
        /**
         * 全文检索查询:match、multi_match
         */
        @Test
        void testMatch() throws IOException {
            // 1.准备request
            SearchRequest request = new SearchRequest("hotel");
            // 2.准备请求参数
            //request.source().query(QueryBuilders.matchQuery("all", "外滩如家"));
            request.source().query(QueryBuilders.multiMatchQuery("外滩如家", "name", "brand", "city"));
            // 3.发送请求,得到响应
            SearchResponse response = client.search(request, RequestOptions.DEFAULT);
            // 4.结果解析
            handleResponse(response);
        }
    
        /**
         * 1.精确查询:term、range
         * 2.boolean组合查询
         * 查询city为杭州,price>=250的文档
         */
        @Test
        void testBool() throws IOException {
            // 1.准备request
            SearchRequest request = new SearchRequest("hotel");
            // 2.准备请求参数
           /*
             BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
            // 2.1.must
            boolQuery.must(QueryBuilders.termQuery("city", "上海"));
            // 2.2.filter
            boolQuery.filter(QueryBuilders.rangeQuery("price").lte(250));
            request.source().query(boolQuery);
            */
    
            request.source().query(
                    QueryBuilders.boolQuery()
                            .must(QueryBuilders.termQuery("city", "上海"))
                            .filter(QueryBuilders.rangeQuery("price").lte(250))
            );
            // 3.发送请求,得到响应
            SearchResponse response = client.search(request, RequestOptions.DEFAULT);
            // 4.结果解析
            handleResponse(response);
        }
    
    
        /**
         * 排序和分页
         */
        @Test
        void testSortAndPage() throws IOException {
            int page = 2,size = 5;
    
            // 1.准备request
            SearchRequest request = new SearchRequest("hotel");
            // 2.准备请求参数
            // 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(size);
    
            // 3.发送请求,得到响应
            SearchResponse response = client.search(request, RequestOptions.DEFAULT);
            // 4.结果解析
            handleResponse(response);
        }
    
        /**
         * 结果高亮
         */
        @Test
        void testHighlight() throws IOException {
            // 1.准备request
            SearchRequest request = new SearchRequest("hotel");
            // 2.准备请求参数
            // 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);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156

    四、案例

    4.1 问题解析

    在这里插入图片描述

    在这里插入图片描述

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

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    4.2 代码

    在这里插入图片描述

    4.2.1 实体bean

    PageResult.java 响应结果类:由搜索框得到的查询结果类

    /**
     * 响应结果类:由搜索框得到的查询结果类
     */
    @Data
    public class PageResult {
        private Long total; // 总条数
        private List<HotelDoc> hotels; // 酒店信息
    
        public PageResult() {
        }
    
        public PageResult(Long total, List<HotelDoc> hotels) {
            this.total = total;
            this.hotels = hotels;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    RequestParams.java 请求参数类:搜索框中有哪些参数

    /**
     * 请求参数类:搜索框中有哪些参数
     */
    @Data
    public class RequestParams {
        private String key;  // 搜索关键字
        private Integer page;// 当前页码
        private Integer size;// 每页大小
        private String sortBy;// 排序字段
        private String brand;// 品牌
        private String city;// 城市
        private String starName;// 星级
        private Integer minPrice;// 最低价格
        private Integer maxPrice;// 最高价格
        private String location;// 位置
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    4.2.2 控制层

    @RestController
    @RequestMapping("hotel")
    public class HotelController {
    
        @Autowired
        private IHotelService hotelService;
    
        @PostMapping("list")
        public PageResult search(@RequestBody RequestParams params) {
            return hotelService.search(params);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    4.2.3 业务service

    public interface IHotelService extends IService<Hotel> {
        PageResult search(RequestParams params);
    }
    
    • 1
    • 2
    • 3
    @Slf4j
    @Service
    public class HotelService extends ServiceImpl<HotelMapper, Hotel> implements IHotelService {
    
        @Autowired
        private RestHighLevelClient restHighLevelClient;
    
        @Override
        public PageResult search(RequestParams params) {
            try {
                // 1.准备Request
                SearchRequest request = new SearchRequest("hotel");
    
                // 2.准备请求参数
    
                // 2.1.多条件查询和过滤
                buildBasicQuery(params, request);
    
                // 2.2.分页
                int page = params.getPage();
                int size = params.getSize();
                request.source().from((page - 1) * size).size(size);
    
                /**
                 * 2.3.距离排序
                 */
                String location = params.getLocation();
                if (StringUtils.isNotBlank(location)) {// 不为空则查询
                    request.source().sort(SortBuilders
                            .geoDistanceSort("location", new GeoPoint(location))
                            .order(SortOrder.ASC)
                            .unit(DistanceUnit.KILOMETERS)
                    );
                }
    
                // 3.发送请求
                SearchResponse response = restHighLevelClient.search(request, RequestOptions.DEFAULT);
    
                // 4.解析响应
                return handleResponse(response);
            } catch (IOException e) {
                throw new RuntimeException("搜索数据失败", e);
            }
        }
    
        private void buildBasicQuery(RequestParams params, SearchRequest request) {
            // 1.准备Boolean复合查询
            BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
    
            /**
             * 1.查询关键字
             * must参与 算分
             */
            // 1.1.关键字搜索,match查询,放到must中
            String key = params.getKey();
            if (StringUtils.isNotBlank(key)) {
                // 不为空,根据关键字查询
                boolQuery.must(QueryBuilders.matchQuery("all", key));
            } else {
                // 为空,查询所有
                boolQuery.must(QueryBuilders.matchAllQuery());
            }
            /**
             * 2.条件过滤:多条件复合查询
             * 根据 “品牌 城市 星级 价格范围” 过滤数据
             * filter不参与 算分
             */
    
            // 1.2.品牌
            String brand = params.getBrand();
            if (StringUtils.isNotBlank(brand)) { // 不为空则查询
                boolQuery.filter(QueryBuilders.termQuery("brand", brand));
            }
            // 1.3.城市
            String city = params.getCity();
            if (StringUtils.isNotBlank(city)) {// 不为空则查询
                boolQuery.filter(QueryBuilders.termQuery("city", city));
            }
            // 1.4.星级
            String starName = params.getStarName();
            if (StringUtils.isNotBlank(starName)) {// 不为空则查询
                boolQuery.filter(QueryBuilders.termQuery("starName", starName));
            }
            // 1.5.价格范围
            Integer minPrice = params.getMinPrice();
            Integer maxPrice = params.getMaxPrice();
            if (minPrice != null && maxPrice != null) {// 不为空则查询
                maxPrice = maxPrice == 0 ? Integer.MAX_VALUE : maxPrice;
                boolQuery.filter(QueryBuilders.rangeQuery("price").gte(minPrice).lte(maxPrice));
            }
    
            /**
             * 3.算分函数查询
             * 置顶功能:给你置顶的酒店添加一个标记,并按其算分
             */
            FunctionScoreQueryBuilder functionScoreQuery = QueryBuilders.functionScoreQuery(
                    boolQuery, // 原始查询,boolQuery
                    new FunctionScoreQueryBuilder.FilterFunctionBuilder[]{ // function数组
                            new FunctionScoreQueryBuilder.FilterFunctionBuilder(
                                    QueryBuilders.termQuery("isAD", true), // 过滤条件
                                    ScoreFunctionBuilders.weightFactorFunction(10) // 算分函数
                            )
                    }
            );
    
            /**
             * 4.设置查询条件
              */
            request.source().query(functionScoreQuery);
        }
    
        private PageResult handleResponse(SearchResponse response) {
            SearchHits searchHits = response.getHits();
            // 4.1.总条数
            long total = searchHits.getTotalHits().value;
            // 4.2.获取文档数组
            SearchHit[] hits = searchHits.getHits();
            // 4.3.遍历
            List<HotelDoc> hotels = new ArrayList<>(hits.length);
            for (SearchHit hit : hits) {
                // 4.4.获取source
                String json = hit.getSourceAsString();
                // 4.5.反序列化,非高亮的
                HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
                // 4.6.处理高亮结果
                // 1)获取高亮map
                Map<String, HighlightField> map = hit.getHighlightFields();
                if (map != null && !map.isEmpty()) {
                    // 2)根据字段名,获取高亮结果
                    HighlightField highlightField = map.get("name");
                    if (highlightField != null) {
                        // 3)获取高亮结果字符串数组中的第1个元素
                        String hName = highlightField.getFragments()[0].toString();
                        // 4)把高亮结果放到HotelDoc中
                        hotelDoc.setName(hName);
                    }
                }
                // 4.8.排序信息
                Object[] sortValues = hit.getSortValues(); // 获取排序结果
                if (sortValues.length > 0) {
                    /**
                     * 由于该程序是根据距离[酒店距你选择位置的距离]进行排序,所以排序结果为距离
                     */
                    hotelDoc.setDistance(sortValues[0]);
                }
    
                // 4.9.放入集合
                hotels.add(hotelDoc);
            }
            return new PageResult(total, hotels);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153

    4.2.4 启动类

    @MapperScan("cn.itcast.hotel.mapper")
    @SpringBootApplication
    public class HotelDemoApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(HotelDemoApplication.class, args);
        }
    
        @Bean
        public RestHighLevelClient restHighLevelClient(){
            return new RestHighLevelClient(RestClient.builder(
                    HttpHost.create("http://192.168.1.101:9200")
            ));   // 服务器IP+端口9200
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
  • 相关阅读:
    SpringBoot集成RabbitMQ使用建议
    如何本地部署开源AI知识库 FastGPT(新手教程)
    MFC|按钮的自绘
    Vuex——笔试题、Vuex简介、引入方式、State、Getter、Mutation、Action、Module
    解决AnyViewer干扰控制端输入法的问题
    guacamole安装
    云端日历同步大师:iCloud让工作与生活井井有条
    19.静态内部类【静态嵌套类】【20220701】
    【洛谷P1622】释放囚犯【区间DP】
    Flutter实践一:package组织
  • 原文地址:https://blog.csdn.net/shendaiyan/article/details/136616190