• springBoot+Window下的Elasticsearch实现查询


    1.准备好Elasticsearch环境,这里使用的是window版本。

    1.从官网下载安装包:https://www.elastic.co/cn/downloads/past-releases/elasticsearch-5-6-16

    2.分词器 elasticsearch-analysis-ik:https://github.com/medcl/elasticsearch-analysis-ik/releases/tag/v5.6.16

    3.head插件 地址:https://github.com/mobz/elasticsearch-head

      其他环境:node.js环境(可视化运行界面运行需要),jdk8

    4. 将下载好的安装包解压,进入bin目录运行elasticsearch.bat即可。(需要jdk8的环境)

      

     成功启动后访问:http://localhost:9200/,返回信息:

      

    5. 可以通过head插件查看可视化页面。

    6. 将head解压到(建议解压到Elasticsearch的统计目录,好找),进入到elasticsearch-head-master即可(需要node.js环境)。

      

     7.在此页面数据 grunt server,即可运行。如果提示无法启动。运行命令:npm install -g grunt-cli。

     8.使用可是化界面连接 Elasticsearch 时 需要在Elasticsearch 的配置文件下配置跨域。配置文件位置:elasticsearch-5.6.16configelasticsearch.yml。

      配置内容: http.cors.enabled: true
            http.cors.allow-origin: "*"

      注意:“:” 号后需要加空格

    9.访问 http://localhost:9100/.

     10,现在的 Elasticsearch 就是一个服务器,并且已有了视化界面,我们可以在可视化界面对他进行操作,但在elasticsearch-head-master上操作它时太过于麻烦。

    这里选择postman对他进行操作。在操作之前,先看一下数据库(使用mysql)和索引库之间的关系。深入了解概念可参考:

    https://blog.csdn.net/achang07/article/details/79713245

    对应关系:

     

     11. 首先创建一个索引库,然后在创建一个mapping,或者在创建索引库的同时创建mapping。

      11.1创建索引库

       11.2 创建映射

      查看以下效果

      

     11.3创建索引的同时创建映射

      

     12. 对于elasticsearch的概念暂结束。接下来看后端代码。创建springBoot项目。引入以下依赖。数据库文件

    <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <optional>true</optional>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>1.2.57</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-jdbc</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-jpa</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.47</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
                <exclusions>
                    <exclusion>
                        <groupId>org.junit.vintage</groupId>
                        <artifactId>junit-vintage-engine</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
        </dependencies>

    13. application.yml配置 

    server:
      port: 8888
    spring:
      data:
        elasticsearch:
          cluster-nodes: 127.0.0.1:9300
    #在这配置数库连接是因为,我会从数据库读取数据到索引库中。
      #如果有其他方式读取数据,一下配配置可以不用写
      datasource:
        url: jdbc:mysql://127.0.0.1:3306/jpa
        username: root
        password: sasa
        driver-class-name: com.mysql.jdbc.Driver
        jpa:
          hibernate:
            ddl-auto: update
          show-sql: true

    14.在后端使用创建索引库,首先创建相对应过的实体类。

    package com.los.es.pojo;
    
    import lombok.Data;
    import org.springframework.data.elasticsearch.annotations.Document;
    import org.springframework.data.annotation.Id;
    import org.springframework.data.elasticsearch.annotations.Field;
    import org.springframework.data.elasticsearch.annotations.FieldType;
    
    /**
     * 用于创建索引库,ES
     */
    
    @Data
    //indexName 索引库名称,类型名字:goods
    @Document(indexName = "tb",type = "goods")
    public class Rgoods {
    
        @Id
        private int cid;
    
        @Field(type = FieldType.Keyword,index = true,analyzer = "ik_max_word")
        private String name;
        //其他文档数据默认
        private  int isParent;
        private int parentId;
        private int level;
        private String pathId;
        private String path;
    }

    14.创建索引库并存储数据

    import com.alibaba.fastjson.JSON;
    import com.alibaba.fastjson.JSONObject;
    import com.los.es.EsApplication;
    import com.los.es.config.ResponseResult;
    import com.los.es.pojo.Rgoods;
    import com.los.es.repository.GoodsRepository;
    import com.los.es.repository.RgoodsRepository;
    import org.junit.jupiter.api.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.data.domain.PageRequest;
    import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
    import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
    import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
    
    import java.util.List;
    
    
    @SpringBootTest(classes = EsApplication.class)
    public class Init {
    
        //在导入spring-boot-starter-data-elasticsearch启动器时
        // springboot已经默认配置了这个类
        @Autowired
        private ElasticsearchTemplate template;
        
        //用于调用elasticsearch索引库的接口,如新增,查询,相关代码在后面会贴出来
        @Autowired
        private GoodsRepository goodsRepository;
    
        //用于操作数据库的接口,相关代码在后面会贴出来
        @Autowired
        private RgoodsRepository rgoodsRepository;
    
        //创建索引库
        @Test
        public void createIndex(){
            template.createIndex(Rgoods.class);
        }
    
        //向索引库中填充数据
        @Test
        public void fullData(){
            //使用了Ali的fastJson,将两个类名不一样,但其中的字段名和类型一样的类相互直接赋值
            //因为我需要从数据库将数据读出来,需要建一个实体类对应数据库
            rgoodsRepository.saveAll(JSONObject.parseArray
                    (JSON.toJSONString(goodsRepository.findAll()),Rgoods.class));
        }

    15.项目结构,该案例使用jpa操作数据库。

     16,Goods实体类

    package com.los.es.pojo;
    
    import javax.persistence.*;
    
    @Entity
    @Table(name = "wp_ex_source_goods_tb_cat_copy")
    public class Goods {
    
        @Id
        @Column(name = "cid",insertable = false,updatable = false)
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        private int cid;
    
        @Column(name = "name")
        private String name;
    
        @Column(name = "is_parent")
        private  int isParent;
    
        @Column(name = "parent_id")
        private int parentId;
    
        @Column(name = "level")
        private int level;
    
        @Column(name = "pathid")
        private String pathId;
    
        @Column(name = "path")
        private String path;
    
        public int getCid() {
            return cid;
        }
    
        public void setCid(int cid) {
            this.cid = cid;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getIsParent() {
            return isParent;
        }
    
        public void setIsParent(int isParent) {
            this.isParent = isParent;
        }
    
        public int getParentId() {
            return parentId;
        }
    
        public void setParentId(int parentId) {
            this.parentId = parentId;
        }
    
        public int getLevel() {
            return level;
        }
    
        public void setLevel(int level) {
            this.level = level;
        }
    
        public String getPathId() {
            return pathId;
        }
    
        public void setPathId(String pathId) {
            this.pathId = pathId;
        }
    
        public String getPath() {
            return path;
        }
    
        public void setPath(String path) {
            this.path = path;
        }
    
    }

    17.Rgoods

    package com.los.es.pojo;
    
    import lombok.Data;
    import org.springframework.data.elasticsearch.annotations.Document;
    import org.springframework.data.annotation.Id;
    import org.springframework.data.elasticsearch.annotations.Field;
    import org.springframework.data.elasticsearch.annotations.FieldType;
    
    /**
     * 用于创建索引库,ES
     */
    
    @Data
    //indexName 索引库名称,类型名字:goods
    @Document(indexName = "tb",type = "goods")
    public class Rgoods {
    
        @Id
        private int cid;
    
        @Field(type = FieldType.Keyword,index = true,analyzer = "ik_max_word")
        private String name;
        //其他文档数据默认
        private  int isParent;
        private int parentId;
        private int level;
        private String pathId;
        private String path;
    }

    18

    .

     19.

    20.CorsConfig 配置类

    package com.los.es.config;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.cors.CorsConfiguration;
    import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
    import org.springframework.web.filter.CorsFilter;
    
    @Configuration
    public class CorsConfig {
        // 初始化 CorsConfiguration 对象并设置允许的域名、请求头部信息和请求方式
        private CorsConfiguration buildConfig() {
            CorsConfiguration corsConfiguration = new CorsConfiguration();
            corsConfiguration.addAllowedOrigin("*"); // 1 允许任何域名使用
            corsConfiguration.addAllowedHeader("*"); // 2 允许任何头
            corsConfiguration.addAllowedMethod("*"); // 3 允许任何方法(post、get 等)
            return corsConfiguration;
        }
        /**
         * 创建 CorsFilter 对象
         * @return CorsFilter
         */
        @Bean
        public CorsFilter corsFilter() {
            UrlBasedCorsConfigurationSource source = new
                    UrlBasedCorsConfigurationSource();
            source.registerCorsConfiguration("/**", buildConfig()); //拦截所有请求
            return new CorsFilter(source);
        }
    }

    21. RequestResult

    package com.los.es.config;
    
    public class RequestResult {
        //查询条件
        private String searchKey;
        //当前页
        private Integer page;
    
        //当前页显示条数
        private Integer size;
    
        private static final Integer DEFAULT_SIZE = 20;// 每页大小,不从页面接收,而是固定大小
        private static final Integer DEFAULT_PAGE = 1;// 默认页
    
        public String getSearchKey() {
            return searchKey;
        }
    
        public void setSearchKey(String searchKey) {
            this.searchKey = searchKey;
        }
    
        public Integer getPage() {
            if(page == null){
                return DEFAULT_PAGE;
            }
            // 获取页码时做一些校验,不能小于1
            return Math.max(DEFAULT_PAGE, page);
        }
    
        public void setPage(Integer page) {
            this.page = page;
        }
    
        public Integer getSize() {
            if(size == null){
                return DEFAULT_SIZE;
            }
            return size;
        }
    
        public void setSize(Integer size) {
            this.size = size;
        }
    }

    22. ResponseResult

    package com.los.es.config;
    
    import com.los.es.pojo.Rgoods;
    
    import java.util.List;
    
    /**
     * 返回结果
     */
    public class ResponseResult {
        private int currentPage;
        private int pageSize;
        private int total;
        private List<Rgoods> rgoods;
    
        public int getCurrentPage() {
            return currentPage;
        }
    
        public void setCurrentPage(int currentPage) {
            this.currentPage = currentPage;
        }
    
        public int getPageSize() {
            return pageSize;
        }
    
        public void setPageSize(int pageSize) {
            this.pageSize = pageSize;
        }
    
        public int getTotal() {
            return total;
        }
    
        public void setTotal(int total) {
            this.total = total;
        }
    
        public List<Rgoods> getRgoods() {
            return rgoods;
        }
    
        public void setRgoods(List<Rgoods> rgoods) {
            this.rgoods = rgoods;
        }
        /**
         *
         */
    }

    23. GoodsService 服务层

    package com.los.es.service;
    
    import com.los.es.config.RequestResult;
    import com.los.es.config.ResponseResult;
    import com.los.es.pojo.Rgoods;
    import com.los.es.repository.RgoodsRepository;
    import org.elasticsearch.index.query.QueryBuilders;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.data.domain.PageRequest;
    import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
    import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
    import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;
    import org.springframework.util.StringUtils;
    
    @Service
    @Transactional
    public class GoodsService {
    
        @Autowired
        private RgoodsRepository rgoodsRepository;
    
        @Autowired
        private ElasticsearchTemplate template;
    
    
        public ResponseResult findByKey(RequestResult request){
            int page = request.getPage() - 1;
            int size = request.getSize();
            ResponseResult rs = new ResponseResult();
            //自定义查询方法
            NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
            //分页
            queryBuilder.withPageable(PageRequest.of(page, size));
            //过滤
            if(!StringUtils.isEmpty(request.getSearchKey())){//条件为空时
                queryBuilder.withQuery(QueryBuilders.matchQuery("name", request.getSearchKey()));
            }
            //查询
            AggregatedPage<Rgoods> rgoods = template.queryForPage(queryBuilder.build(), Rgoods.class);
            //需要显示的数据
            rs.setRgoods( rgoods.getContent());
            rs.setCurrentPage(rgoods.getNumber());
            rs.setTotal((int)rgoods.getTotalElements());
            rs.setPageSize(rgoods.getSize());
            return rs;
        }
    }

    24. web

    package com.los.es.web;
    
    import com.los.es.config.RequestResult;
    import com.los.es.config.ResponseResult;
    import com.los.es.service.GoodsService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class RgoodsController {
    
        @Autowired
        private GoodsService goodsService;
    
        @GetMapping("find")
        public ResponseResult find(RequestResult requestResult){
            return goodsService.findByKey(requestResult);
        }
    }

     25.前端使用比较简陋,使用vue实现。首先创建vue项目,引入ElementUi和axios。单页面就直接贴代码了

    <template>
      <div class="hello">
        <input v-on:input="inputFun" placeholder="搜索" type="text" @keyup.enter="searchEnterFun" size="mini" v-model="search">
      
        <el-select
        v-model="value"
        multiple
        filterable
        remote
        reserve-keyword
        placeholder="请输入关键词"
        :remote-method="remoteMethod"
        :loading="loading">
        <el-option
          v-for="item in options"
          :key="item.value"
          :label="item.label"
          :value="item.value">
        </el-option>
      </el-select>
        <el-table v-loading="loading" :data = "tableData" style=" 100%">
        <el-table-column
          label="level"
          prop="date">
        </el-table-column>
        <el-table-column
          label="Name"
          prop="name">
        </el-table-column>
        <el-table-column
          align="right">
          <template slot="header" slot-scope="scope">
          </template>
        </el-table-column>
      </el-table>
      <!-- 分页 -->
       <el-pagination
                background
                @size-change="handleSizeChange"
                @current-change="handleCurrentChange"
                :current-page="currentPage"
                :page-sizes="[20, 30, 40, 50]"
                :page-size="pageSize"
                layout="total, sizes, prev, pager, next, jumper"
                :total="total">
        </el-pagination>
      </div>
    </template>
    
    <script>
    const axios = require("axios");
    export default {
      name: 'HelloWorld',
      data () {
        return {
            options: [],
            value: [],
            list: [],
           states: [],
          tishiloading:false,
          loading:false,
           currentPage:0,// 当前页码
           pageSize:0,// 每页大小
           total:0, //总条数  ,以上值在初始化时赋予
           tableData: [],
           search: ''
          }
        },
        created() {
          this.init()
        },
         methods: {
           init: function(h) {
            //alert("初始化信息")
            var app=this;
            var a=h==undefined?app:h
            console.log('init')
            axios
              .get("http://localhost:8888/find")
              .then(function(response) {
                a.states = response.data.rgoods
                a.list = a.states.map(item => {
                return {
                   value: item.name, label: item.name
                };
                });
                  a.tableData = response.data.rgoods
                  a.total = response.data.total
                  a.pageSize = response.data.pageSize
                  a.currentPage = response.data.currentPage
                })
              .catch(function(error) {
                console.log(error);
                });
            },
    
        //但用户输入时触发函数
        inputFun(){
             var vm = this 
              vm.loading = true
        },
    
           //回车事件
          searchEnterFun(){
            var vm = this 
             axios
               .get("http://localhost:8888/find",{
                 params:{
                  size:vm.pageSize,
                  page:vm.pageNumber,
                  searchKey:vm.search
                 }
               }).then(function(response){
                  vm.tableData = response.data.rgoods
                  vm.total = response.data.total
                  vm.pageSize = response.data.pageSize
                  vm.pageNumber = response.data.pageNumber
                  vm.loading =false
               }).catch(function(error){
                    console.log(error)
               })
          },
    
          //长度改变----改变每页显示的条数的时候  自动触发
           handleSizeChange(val){
             var vm = this 
               console.log("长度改变:"+val+"--当前页"+vm.currentPage)
               axios
               .get("http://localhost:8888/find",{
                 params:{
                  size:val,
                  page:vm.pageNumber,
                  searchKey:vm.search
                 }
               }).then(function(response){
                  vm.tableData = response.data.rgoods
                  vm.total = response.data.total
                  vm.pageSize = response.data.pageSize
               }).catch(function(error){
                    console.log(error)
               })
           },
    
            // 当前改变----当前页码改变之后(上下页),触发这个函数
           handleCurrentChange(val){
               var vm = this
               console.log("当前改变:"+val+"每页显示条数"+vm.pageSize)
                axios
              .get("http://localhost:8888/find",{
                params:{
                  page:val,
                  size:vm.pageSize,
                  searchKey:vm.search
                }
              })
              .then(function(response) { 
                  vm.tableData = response.data.rgoods
                  vm.total = response.data.pageInfo.total
                  vm.pageSize = response.data.pageInfo.pageSize
                  vm.currentPage = response.data.currentPage
              })
              .catch(function(error) {
                console.log(error);
                });
            },
           },
    
    }
    </script>
    
    
    <style scoped>
    
    </style>
  • 相关阅读:
    我渴望自由和成功(愿与君共勉)
    gdb使用 和core dump文件调试
    谷歌浏览器快捷键大全
    Android适屏
    BestCoder Round #33
    NAT&amp;Port Forwarding&amp;Port Triggering
    程序员应该学习的书
    java代码调用rtx发送提醒消息
    js实现excel导出
    一个跨界程序员:不务正业的这几年,我如何让自己的收入翻了十倍(转)
  • 原文地址:https://www.cnblogs.com/autonomy/p/11865865.html
Copyright © 2020-2023  润新知