Spring boot 整合 Elasticsearch 实现模糊查询

大家好,今天突发奇想,,学习拉一下Elasticsearch,今天来跟大家分享一下,平时不熬夜得的我,最近熬夜搞这个东西,可能不是那么完美,也会有小bug,所以请大家谅解 Spring boot 整合 Elasticsearch 实现模糊查询_第1张图片

1:安装Elasticsearch

去官网下载https://www.elastic.co/cn/downloads/elasticsearch
Spring boot 整合 Elasticsearch 实现模糊查询_第2张图片
下面运行Elasticsearch
下载完解压即可:直接双击/bin/ElasticSearch.bat
在这里插入图片描述
运行成功之后,就在浏览器输入http://localhost:9200
Spring boot 整合 Elasticsearch 实现模糊查询_第3张图片
如图所示;

二:安装elasticsearch-head

这里不做详情解说哦;
然后我们:
同样输入框:cmd 到该目录

输入命令 npm install 回车执行

输入 npm run start 启动服务
Spring boot 整合 Elasticsearch 实现模糊查询_第4张图片
这样之后在浏览器中输入:http://localhost:9100 查看

三、安装logstash

下载地址:https://www.elastic.co/downloads/logstash
解压压缩包之后我们就连接数据库
logstash-mysql.conf 文件内容

input {
    stdin {
    }
    #如果需要同步多个表,那么重复配置jdbc{}这一部分,只需要修改表相关的部分
    jdbc {
      # 数据库  数据库名称为test,表名为users
      jdbc_connection_string => "jdbc:mysql://localhost:3306/elasticsearch"
      # 用户名密码
      jdbc_user => "root"
      jdbc_password => "******"
      # jar包的位置(把jar包直接放到logstash-core/lib/jars下)
      jdbc_driver_library => "E:\logstash-7.4.2\logstash-core\lib\jars\mysql-connector-java-5.1.39-bin.jar"
      # mysql的Driver
      jdbc_driver_class => "com.mysql.jdbc.Driver"
      jdbc_paging_enabled => "true"
      jdbc_page_size => "50000"
      #statement_filepath => "config-mysql/book.sql"
      #这里的sql效果是:全量同步、增量更新users表。 如果需要全量同步以及更新users表,则select * from users即可。
      statement => "select * from car"
      #定时字段 各字段含义(由左至右)分、时、天、月、年,全部为*默认含义为每分钟都更新(cron表达式)
      schedule => "* * * * *"
	  #索引的类型
      type => "_doc"
    }
}
 
filter {
    json {
        source => "message"
        remove_field => ["message"]
    }
}
 
output {
    elasticsearch {
        hosts => "127.0.0.1:9200"
        # index名
		index => "goods"
		# 需要关联的数据库中要有一个id字段(最好就是表的主键),对应索引的id号
        document_id => "%{cid}"
    }
    stdout {
        codec => json_lines
    }
}

切记,有些东西改成自己;然后这个conf放在logstash-7.4.2中bin目录下
现在我们打开cmd,在框中输入grunt server 就会发现会报错,这个时候,输入cmd 输入 npm install -g grunt-cli (建议在logstash-7.4.2中打开cmd)
然后再输入grunt -version
Spring boot 整合 Elasticsearch 实现模糊查询_第5张图片
出现版本说明成功啦

四:后台代码

Spring boot 整合 Elasticsearch 实现模糊查询_第6张图片
日常分享项目架构

config里面的代码上两篇文件已经分享过,可以去上文copy
application.yml

server:
  port: 8989
spring:
  data:
    elasticsearch:
      cluster-name: elasticsearch
      cluster-nodes: 127.0.0.1:9300
  jackson:
    default-property-inclusion: non_null
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/elasticsearch?useSSL=false
    username: root
    password: ******
    driver-class-name: com.mysql.jdbc.Driver
  jpa:
   hibernate:
    ddl-auto: update
    show-sql: true

pojo层
goods:

package com.demo.elasticsearch.pojo;

import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;


@Data
@Document(indexName = "goods", type = "_doc", shards = 1, replicas = 0)
public class Goods {

    @Id
    private Long cid;
//    @Field(type = FieldType.Keyword, analyzer = "ik_max_word")
//    private String all; // 所有需要被搜索的信息,包含标题,分类,甚至品牌
    @Field(type = FieldType.Keyword, index = true, analyzer = "ik_max_word")
    private String name;
    @Field(type = FieldType.Keyword)
    private String isParent;
    @Field(type = FieldType.Keyword)
    private String parentId;
    @Field(type = FieldType.Keyword)
    private Long level;
    @Field(type = FieldType.Keyword)
    private String pathid;
    @Field(type = FieldType.Keyword, index = true, analyzer = "ik_max_word")
    private String path;
}

Xcgoods

package com.demo.elasticsearch.pojo;

import lombok.Data;

import javax.persistence.*;
import java.io.Serializable;


@Data
@Entity(name="car")
public class XcGoods implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "cid")
    private Long cid;
    @Column(name = "name")
    private String name;
    @Column(name = "is_parent")
    private String isParent;
    @Column(name = "parent_id")
    private String parentId;
    @Column(name = "level")
    private Long level;
    @Column(name = "pathid")
    private String pathid;
    @Column(name = "path")
    private String path;
}

SearchRequest.java

package com.demo.elasticsearch.pojo;


public class SearchRequest {
    private String key;// 搜索条件

    private Integer page;// 当前页

    private static final Integer DEFAULT_SIZE = 20;// 每页大小,不从页面接收,而是固定大小
    private static final Integer DEFAULT_PAGE = 1;// 默认页

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }

    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() {
        return DEFAULT_SIZE;
    }
}

SearchResult.java

package com.demo.elasticsearch.pojo;

import com.demo.elasticsearch.utils.PageResult;
import lombok.Data;

import java.util.List;
import java.util.Map;

@Data
public class SearchResult extends PageResult {


    public SearchResult() {
    }

    public SearchResult(Long total, Long totalPage, List items) {
        super(total,totalPage,items);
    }
}

下面是Dao层代码
GoodsRepository.java

package com.demo.elasticsearch.repository;

import com.demo.elasticsearch.pojo.Goods;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;

public interface GoodsRepository extends ElasticsearchRepository {

}

XcGoodsRepository.java

package com.demo.elasticsearch.repository;

import com.demo.elasticsearch.pojo.Goods;
import com.demo.elasticsearch.pojo.XcGoods;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;

public interface XcGoodsRepository extends JpaRepository, JpaSpecificationExecutor {

}

Service层
SearchService.java

package com.demo.elasticsearch.service;


import com.demo.elasticsearch.pojo.Goods;
import com.demo.elasticsearch.pojo.SearchRequest;
import com.demo.elasticsearch.pojo.XcGoods;
import com.demo.elasticsearch.utils.PageResult;


public interface SearchService {

    Goods buildGoods(XcGoods goods);

    PageResult search(SearchRequest request);

}

下面实现我们的service层

package com.demo.elasticsearch.service.impl;

import com.demo.elasticsearch.pojo.Goods;
import com.demo.elasticsearch.pojo.SearchRequest;
import com.demo.elasticsearch.pojo.SearchResult;
import com.demo.elasticsearch.pojo.XcGoods;
import com.demo.elasticsearch.repository.GoodsRepository;
import com.demo.elasticsearch.service.SearchService;
import com.demo.elasticsearch.utils.PageResult;
import lombok.extern.slf4j.Slf4j;
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.FetchSourceFilter;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;

import java.util.List;


@Slf4j
@Service
public class SearchServiceImpl implements SearchService {


    @Autowired
    private GoodsRepository goodsRepository;

    @Autowired
    private ElasticsearchTemplate template;

    @Override
    public Goods buildGoods(XcGoods xcgoods) {
        //搜索字段
//        String all =  xcgoods.getName();

        //构建goods对象
        Goods goods = new Goods();
        goods.setCid(xcgoods.getCid());
        goods.setName(xcgoods.getName());
        goods.setIsParent(xcgoods.getIsParent());
        goods.setParentId(xcgoods.getParentId());
        goods.setPathid(xcgoods.getPathid());
        goods.setPath(xcgoods.getPath());
        goods.setLevel(xcgoods.getLevel());
        // 搜索字段,包含标题,分类,品牌,规格,等等
//        goods.setAll(all);

        return goods;
    }


    @Override
    public PageResult search(SearchRequest request) {
        int page = request.getPage() - 1;
        int size = request.getSize();
        //创建查询构建器
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        //结果过滤
        queryBuilder.withSourceFilter(new FetchSourceFilter(new String[]{"cid", "name"}, null));

        //分页
        queryBuilder.withPageable(PageRequest.of(page, size));
        //过滤
        queryBuilder.withQuery(QueryBuilders.matchQuery("name", request.getKey()));

        //查询
        //Page result = goodsRepository.search(queryBuilder.build());
        AggregatedPage result = template.queryForPage(queryBuilder.build(), Goods.class);

        //解析结果
        //分页结果解析
        long total = result.getTotalElements();
        Integer totalPages1 = result.getTotalPages();    //失效
        Long totalPages = total % size == 0 ? total / size : total / size + 1;
        List goodsList = result.getContent();

        //解析聚合结果

        return new SearchResult(total, totalPages, goodsList);
     }


}

util包

package com.demo.elasticsearch.utils;


import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class PageResult {
    private Long total;// 总条数
    private Long totalPage;// 总页数
    private List items;// 当前页数据

    public PageResult(Long total, List items) {
        this.total = total;
        this.items = items;
    }
}

最后就是我们的controller层

package com.demo.elasticsearch.web;

import com.demo.elasticsearch.pojo.Goods;
import com.demo.elasticsearch.pojo.SearchRequest;
import com.demo.elasticsearch.service.SearchService;
import com.demo.elasticsearch.utils.PageResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class SearchController {
    @Autowired
    private SearchService searchService;

    /**
     * 搜索功能
     * @param request
     * @return
     */
    @GetMapping("search")
    public ResponseEntity> search(SearchRequest request) {
        return ResponseEntity.ok(searchService.search(request));
    }
}

到这里我们的后台代码就结束啦
下面分享我的前台,,我前台代码是Vue写的,可以参考,我写啦两种方式
第一种方式就是,我有一个表格,有一个搜索框,点击查询之后将数据显示在表格中:








这种的话就比较传统,可以参考这种,但是我这里有个问题就是我只能显示id和name,所以可能要根据自己的字段个数对table做增减
还有一种就是我在搜索框内输入文字,然后他实时显示,将他显示在下拉框:







这个的话就比较新奇吧,可根据个人爱好选择哪一个方式

到这里我们的代码就分享完了,如果有什么疑问可随时私聊我哦,谢谢

Spring boot 整合 Elasticsearch 实现模糊查询_第7张图片

你可能感兴趣的:(Spring,boot,+,Elasticsearch,+Jpa,+V)