• elasticsearch代码基本实现


    pom

    
        org.springframework.boot
        spring-boot-starter-parent
        2.3.10.RELEASE
         
    
    cn.itcast.demo
    hotel-demo
    0.0.1-SNAPSHOT
    hotel-demo
    Demo project for Spring Boot
    
        1.8
        7.12.1
    
    
        
            org.springframework.boot
            spring-boot-starter-web
        
        
            com.baomidou
            mybatis-plus-boot-starter
            3.4.2
        
        
            mysql
            mysql-connector-java
            runtime
        
        
            org.projectlombok
            lombok
            true
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
            
                
                    org.junit.vintage
                    junit-vintage-engine
                
            
        
        
        
            com.alibaba
            fastjson
            1.2.71
        
        
            org.elasticsearch.client
            elasticsearch-rest-high-level-client
          
        
        
            org.apache.commons
            commons-lang3
        
    
    
    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
                
                    
                        
                            org.projectlombok
                            lombok
                        
                    
                
            
        
    

    =======================================

    yml

    server:
      port: 8089
    spring:
      datasource:
        url: jdbc:mysql://localhost:3306/db1?useSSL=false
        username: root
        password: 1234
        driver-class-name: com.mysql.jdbc.Driver
    logging:
      level:
        cn.itcast: debug
      pattern:
        dateformat: MM-dd HH:mm:ss:SSS
    mybatis-plus:
      configuration:
        map-underscore-to-camel-case: true
      type-aliases-package: cn.itcast.hotel.pojo

    ========================

    索引库

    import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
    import org.elasticsearch.client.RequestOptions;
    import org.elasticsearch.client.RestClient;
    import org.elasticsearch.client.indices.CreateIndexRequest;
    import org.elasticsearch.client.indices.GetIndexRequest;
    import org.elasticsearch.common.xcontent.XContentType;
    import org.junit.jupiter.api.AfterEach;
    import org.junit.jupiter.api.BeforeEach;
    import org.elasticsearch.client.RestHighLevelClient;
    import org.junit.jupiter.api.Test;
    
    
    import java.io.IOException;
    
    import static cn.itcast.hotel.HotelConstants.MAPPING_TEMPLATE;
    
    public class HotelIndexTest {
    
        private RestHighLevelClient client;
    
        @BeforeEach
        void setUp() {
            this.client = new RestHighLevelClient(RestClient.builder(
                    HttpHost.create("http://IP:9200")
            ));
        }
    
        @AfterEach
        void tearDown() throws IOException {
            this.client.close();
        }
        @Test
        void createHotelIndex() throws IOException {
            // 1.创建Request对象
            CreateIndexRequest request = new CreateIndexRequest("hotel2");
            // 2.准备请求的参数:DSL语句
            request.source(MAPPING_TEMPLATE, XContentType.JSON);
            // 3.发送请求
           client.indices().create(request,RequestOptions.DEFAULT);
        }
    
        @Test
        void testDeleteHotelIndex() throws IOException {
            // 1.创建Request对象
            DeleteIndexRequest request = new DeleteIndexRequest("hotel");
            // 2.发送请求
            client.indices().delete(request, RequestOptions.DEFAULT);
        }
    
        @Test
        void testExistsHotelIndex() throws IOException {
    
            // 1.创建Request对象
            GetIndexRequest request = new GetIndexRequest("hotel");
            // 2.发送请求
            boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
            // 3.输出
            System.err.println(exists ? "索引库已经存在!" : "索引库不存在!");
        }
    }
    

    =========================

    mapping字段

    public class HotelConstants {
        public static final String MAPPING_TEMPLATE =
               "{\n" +
                       "  \"mappings\": {\n" +
                       "    \"properties\": {\n" +
                       "      \"id\": {\n" +
                       "        \"type\": \"keyword\"\n" +
                       "      },\n" +
                       "      \"name\":{\n" +
                       "        \"type\": \"text\",\n" +
                       "        \"analyzer\": \"ik_max_word\",\n" +
                       "        \"copy_to\": \"all\"\n" +
                       "      },\n" +
                       "      \"address\":{\n" +
                       "        \"type\": \"keyword\",\n" +
                       "        \"index\": false\n" +
                       "      },\n" +
                       "      \"price\":{\n" +
                       "        \"type\": \"integer\"\n" +
                       "      },\n" +
                       "      \"score\":{\n" +
                       "        \"type\": \"integer\"\n" +
                       "      },\n" +
                       "      \"brand\":{\n" +
                       "        \"type\": \"keyword\",\n" +
                       "        \"copy_to\": \"all\"\n" +
                       "      },\n" +
                       "      \"city\":{\n" +
                       "        \"type\": \"keyword\",\n" +
                       "        \"copy_to\": \"all\"\n" +
                       "      },\n" +
                       "      \"starName\":{\n" +
                       "        \"type\": \"keyword\"\n" +
                       "      },\n" +
                       "      \"business\":{\n" +
                       "        \"type\": \"keyword\"\n" +
                       "      },\n" +
                       "      \"location\":{\n" +
                       "        \"type\": \"geo_point\"\n" +
                       "      },\n" +
                       "      \"pic\":{\n" +
                       "        \"type\": \"keyword\",\n" +
                       "        \"index\": false\n" +
                       "      },\n" +
                       "      \"all\":{\n" +
                       "        \"type\": \"text\",\n" +
                       "        \"analyzer\": \"ik_max_word\"\n" +
                       "      }\n" +
                       "    }\n" +
                       "  }\n" +
                       "}";
    }
    

    ==================

    DOC文档

    import cn.itcast.hotel.pojo.Hotel;
    import cn.itcast.hotel.pojo.HotelDoc;
    import cn.itcast.hotel.service.IHotelService;
    import com.alibaba.fastjson.JSON;
    import org.apache.http.HttpHost;
    import org.elasticsearch.action.bulk.BulkRequest;
    import org.elasticsearch.action.delete.DeleteRequest;
    import org.elasticsearch.action.get.GetRequest;
    import org.elasticsearch.action.get.GetResponse;
    import org.elasticsearch.action.index.IndexRequest;
    import org.elasticsearch.action.update.UpdateRequest;
    import org.elasticsearch.client.RequestOptions;
    import org.elasticsearch.client.RestClient;
    import org.elasticsearch.client.RestHighLevelClient;
    import org.elasticsearch.common.xcontent.XContentType;
    import org.junit.jupiter.api.AfterEach;
    import org.junit.jupiter.api.BeforeEach;
    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.List;
    
    
    @SpringBootTest
    class HotelDemoApplicationTests {
        @Autowired
        private IHotelService hotelService;
    
        private RestHighLevelClient client;
    
        @BeforeEach
        void setUp() {
            this.client = new RestHighLevelClient(RestClient.builder(
                    HttpHost.create("http://ip:9200")
            ));
        }
    
        @AfterEach
        void tearDown() throws IOException {
            this.client.close();
        }
    
    
        /*添加一个文档*/
        @Test
        void testAddDocument() throws IOException {
            // 1.根据id查询酒店数据
            Hotel hotel = hotelService.getById(61083L);
            // 2.转换为文档类型
            HotelDoc hotelDoc = new HotelDoc(hotel);
            // 3.将HotelDoc转json
            String json = JSON.toJSONString(hotelDoc);
    
            // 1.准备Request对象
            IndexRequest request = new IndexRequest("hotel").id(hotelDoc.getId().toString());
            // 2.准备Json文档
            request.source(json, XContentType.JSON);
            // 3.发送请求
            client.index(request, RequestOptions.DEFAULT);
        }
    
        /*查询一个文档*/
        @Test
        void testGetDocumentById() throws IOException {
            // 1.准备Request
            GetRequest request = new GetRequest("hotel", "61083");
            // 2.发送请求,得到响应
            GetResponse response = client.get(request, RequestOptions.DEFAULT);
            // 3.解析响应结果
            String json = response.getSourceAsString();
    
            HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
            System.out.println(hotelDoc);
        }
    
        /*删除一个文档*/
        @Test
        void testDeleteDocument() throws IOException {
            // 1.准备Request
            DeleteRequest request = new DeleteRequest("hotel", "61083");
            // 2.发送请求
            client.delete(request, RequestOptions.DEFAULT);
        }
        /*更新一个文档*/
        @Test
        void testUpdateDocument() throws IOException {
            // 1.准备Request
            UpdateRequest request = new UpdateRequest("hotel", "61083");
            // 2.准备请求参数
            request.doc(
                    "price", "952",
                    "starName", "四钻"
            );
            // 3.发送请求
            client.update(request, RequestOptions.DEFAULT);
        }
    
    
        /*批量添加*/
        @Test
        void testBulkRequest() throws IOException {
            // 批量查询酒店数据
            List hotels = hotelService.list();
    
            // 1.创建Request
            BulkRequest request = new BulkRequest();
            // 2.准备参数,添加多个新增的Request
            for (Hotel hotel : hotels) {
                // 2.1.转换为文档类型HotelDoc
                HotelDoc hotelDoc = new HotelDoc(hotel);
                // 2.2.创建新增文档的Request对象
                request.add(new IndexRequest("hotel")
                        .id(hotelDoc.getId().toString())
                        .source(JSON.toJSONString(hotelDoc), XContentType.JSON));
            }
            // 3.发送请求
            client.bulk(request, RequestOptions.DEFAULT);
        }
    }
    

    ===============================

    查询所有

    import cn.itcast.hotel.pojo.HotelDoc;
    
    import com.alibaba.fastjson.JSON;
    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.index.query.QueryBuilders;
    import org.elasticsearch.search.SearchHit;
    import org.elasticsearch.search.SearchHits;
    import org.junit.jupiter.api.AfterEach;
    import org.junit.jupiter.api.BeforeEach;
    import org.junit.jupiter.api.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    
    import java.io.IOException;
    
    
    @SpringBootTest
    public class HotelSearch {
        private RestHighLevelClient client;
    
        @BeforeEach
        void setUp() {
            this.client = new RestHighLevelClient(RestClient.builder(
                    HttpHost.create("http://IP:9200")
            ));
        }
    
        @AfterEach
        void tearDown() throws IOException {
            this.client.close();
        }
    
        @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.解析响应
            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);
            }
        }
    }
    

    =====================

    按单字段搜索

    @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);
    
        // 4.解析响应
        handleResponse(response);
    }

    =============================

    按多字段查询

    @Test
    void testMutilMatch() throws IOException {
        // 1.准备Request
        SearchRequest request = new SearchRequest("hotel");
        // 2.准备DSL/*查询内容,字段*****/
        request.source()
                .query(QueryBuilders.multiMatchQuery("如家","name","business"));
        // 3.发送请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
    
        // 4.解析响应
        handleResponse(response);
    }

    ==============================

    精确查询

    @Test
    void testTerm() throws IOException {
        // 1.准备Request
        SearchRequest request = new SearchRequest("hotel");
        // 2.准备DSL/*查询内容,字段*****/
        request.source()
                .query(QueryBuilders.termQuery("city","北京"));
        // 3.发送请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
    
        // 4.解析响应
        handleResponse(response);
    }

    ======================

    范围查询

    @Test
    void testRange() throws IOException {
        // 1.准备Request
        SearchRequest request = new SearchRequest("hotel");
        // 2.准备DSL
        request.source()
                .query(QueryBuilders.rangeQuery("price").gte(100).lte(150));
        // 3.发送请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
    
        // 4.解析响应
        handleResponse(response);
    }

    =======================

    布尔查询

    @Test
    void testBoolean() 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);
        // 4.解析响应
        handleResponse(response);
    }
    

    ================

    排序分页

    @Test
    void testPageAndSort() throws IOException {
        // 页码,每页大小
        int page = 1, 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);

    }

    ================

    高亮查询

    import org.springframework.util.CollectionUtils;
    @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.解析响应
        handleResponse2(response);
    
    }
    
    
    private void handleResponse2(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 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);
        }
    }

    ========================================

    高级查询

    @Service
    public class HotelService extends ServiceImpl implements IHotelService {
        @Autowired
        private RestHighLevelClient client;
    
        @Override
        public PageResult search(RequestParams params) {
            try {
               /* params.setPage(2);
                params.setSize(5);*/
                // 1.准备Request
                SearchRequest request = new SearchRequest("hotel");
                // 2.准备DSL
                // 2.1.query
                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 (location != null && !location.equals("")) {
                    request.source().sort(SortBuilders
                            .geoDistanceSort("location", new GeoPoint(location))
                            .order(SortOrder.ASC)
                            .unit(DistanceUnit.KILOMETERS)
                    );
                }
    
                // 3.发送请求
                SearchResponse response = client.search(request, RequestOptions.DEFAULT);
                // 4.解析响应
                return handleResponse(response);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    
        private void buildBasicQuery(RequestParams params, SearchRequest request) {
            // 1.构建BooleanQuery
            BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
            // 2.关键字搜索
            String key = params.getKey();
            if (key == null || "".equals(key)) {
                boolQuery.must(QueryBuilders.matchAllQuery());
            } else {
                boolQuery.must(QueryBuilders.matchQuery("all", key));
            }
            // 3.城市条件
            if (params.getCity() != null && !params.getCity().equals("")) {
                boolQuery.filter(QueryBuilders.termQuery("city", params.getCity()));
            }
            // 4.品牌条件
            if (params.getBrand() != null && !params.getBrand().equals("")) {
                boolQuery.filter(QueryBuilders.termQuery("brand", params.getBrand()));
            }
            // 5.星级条件
            if (params.getStarName() != null && !params.getStarName().equals("")) {
                boolQuery.filter(QueryBuilders.termQuery("starName", params.getStarName()));
            }
            // 6.价格
            if (params.getMinPrice() != null && params.getMaxPrice() != null) {
                boolQuery.filter(QueryBuilders
                        .rangeQuery("price")
                        .gte(params.getMinPrice())
                        .lte(params.getMaxPrice())
                );
            }
            // 7.算分控制
            FunctionScoreQueryBuilder functionScoreQuery =
                    QueryBuilders.functionScoreQuery(
                            // 原始查询,相关性算分的查询
                            boolQuery,
                            // function score的数组
                            new FunctionScoreQueryBuilder.FilterFunctionBuilder[]{
                                    // 其中的一个function score 元素
                                    new FunctionScoreQueryBuilder.FilterFunctionBuilder(
                                            // 过滤条件
                                            QueryBuilders.termQuery("isAD", true),
                                            // 算分函数
                                            ScoreFunctionBuilders.weightFactorFunction(10)
                                    )
                            });
            // 8.放入source
            request.source().query(boolQuery);
        }
    
        // 结果解析
        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 hotels = new ArrayList<>();
            for (SearchHit hit : hits) {
                // 获取文档source
                String json = hit.getSourceAsString();
                // 反序列化
                HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
                //获取排序值
                Object[] sortValues = hit.getSortValues();
                if (sortValues.length > 0) {
                    Object sortValue = sortValues[0];
                    hotelDoc.setDistance(sortValue);
                }
                // 放入集合
                hotels.add(hotelDoc);
            }
            // 4.4.封装返回
            return new PageResult(total, hotels);
        }
    }
    

    ========================================

    /*  client.indices().delete 创建索引库
     *  client.indices().create  删除索引库
     *  client.index   创建doc
     *  client.get   获取doc
     *  client.update 更新doc
     *  client.delete  删除doc
     *  client.bulk   批量添加
     *  client.search  查询
     *      request.source()
                .query()
                * QueryBuilders.
                * matchAllQuery; 查询所有
                * multiMatchQuery 多字段模糊查询
                * matchQuery   单字段模糊查询
                * termQuery   精确查询
                * rangeQuery  环绕查询
                * boolQuery   布尔查询
    
     *   request.source().sort("price", SortOrder.ASC); // 2.2.排序 sort
     *  request.source().from((page - 1) * size).size(5);  // 2.3.分页 from、size
     *   request.source().highlighter(new HighlightBuilder().field("name").requireFieldMatch(false));   // 2.2.高亮
     *  // 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));*/
  • 相关阅读:
    (算法设计与分析)第三章动态规划-第一节3:动态规划之使用“找零钱”问题说明最优子结构如何解决
    ZYNQ之FPGA学习----Vivado功能仿真
    推荐系统——召回模型
    leetcode题刷250天(87)——654. 最大二叉树(DFS)
    JS优化多分支结构(经典)
    java计算机毕业设计计算机系教师教研科研管理系统源程序+mysql+系统+lw文档+远程调试
    【iOS】AutoreleasePool自动释放池的实现原理
    Connor学Android - Android消息机制
    Python:一个闹钟
    自定义 cube-ui 弹出框dialog支持多个且多种类型的input框
  • 原文地址:https://blog.csdn.net/weixin_73510682/article/details/128066572