Spring Boost + Elasticsearch 实现检索查询

本文详细介绍了Elasticsearch的倒排索引原理,与MySQL的区别,以及在项目中的数据同步、查询与分页操作。涵盖了增删改查的方法,全文检索和精确查询的使用,以及在单体和微服务架构下的应用策略。
摘要由CSDN通过智能技术生成

需求:对“昵称”进行“全文检索查询”,对“账号”进行“精确查询”。

认识 Elasticsearch 

1. ES 的倒排索引

  1. 正向索引
    1. 对 id 进行检索速度很快。
    2. 对其他字段即使加了索引,只能满足精确查询。
    3. 模糊查询时,逐条数据扫描,判断是否符合条件。速度很慢。
  2. 倒排索引
    1. 词条(Term)+包含词条的所有文档(Document)的id,这种存储形式。

2. ES 与 mysql 的区别

3. ES 的数据结构与表结构

注:id不为long型,而是keyword。即,不参与分词。

4. ES 分词器的种类:

  1. standard
    1. 中文是逐字分词
  2. ik_smart
    1. 粗粒度。
    2. “程序员” = “程序员”
  3. ik_max_word
    1. 细粒度。
    2. “程序员” = “程序员”、“程序”、“员”

5. ES 增删改查:

  1. 指定索引库,对这个索引库进行
    1. 增:PUT
    2. 删:DELETE
    3. 改:PUT,只能新增字段,不能修改旧字段
    4. 查:GET
  2. 指定 id,对这个 id 的文档进行:
    1. 增:POST
    2. 删:DELETE
    3. 改:PUT:替换旧文档,可以实现增+改;POST:指定修改某些字段
    4. 查:GET

6. ES 查询方式:

  1. 全文检索查询
    1. 数据结构:text
    2. 利用分词器对用户输入的内容进行分词,并在倒排查询库中匹配。
    3. match_query:支持一个字段
    4. multi_match_query:支持多个字段,性能不如 match_query。
  2. 精确查询
    1. 数据结构:keyword、数值、日期、boolean
    2. term:精确查询,即等于。
    3. range:只适用于数值、日期。
  3. 其他:地理查询、符合查询等。

配置 Elasticsearch 

  1. 下载 Elasticsearch
    1. Windows10环境下安装Es7_windows安装es7-CSDN博客
    2. 7.x 和 8.x 差距比较大(8.x 版本默认有ssl 认证、用户密码登录,且在 Spring 中的操作差别有点大)。采用版本是7.12.1
    3. 有高、低版本。采用高版本。
    4. 已经不支持 java 访问 ES,而是 java request 请求的方式访问 ES。
  2. 在Spring boot 配置 ES
    1. 在 xml 中引入依赖。且需要在 properties 强制指定 ES 版本为 7.12.1。
  3. 在Spring boot 配置 FastJson
    1. 在 xml 中引入依赖。且需要指定版本为 1.2.68。1.1.x 不支持 LocalDateTime。
  4. 在Spring boot 配置 RabbitMQ
    1. 在 xml 中引入依赖。
    2. 在 yml 中配置 RabbitMQ。

实现 Elasticsearch 

1. 增删改:数据同步

  1. 如果是单体式项目:对数据库进行增删改查时,对ES也进行增删改查
  2. 如果是微服务项目:
    1. 同步调用:
      1. 服务层先操作数据库,再调用更新ES的接口。
      2. 该接口去更新ES。
      3. ES更新完成后,结果返回给接口。
      4. 接口返回给服务层。
      5. 缺点:业务耦合、耗时增加、性能下降。
    2. 异步通知
      1. 服务层操作数据库,再发布消息。
      2. ES监听并更新数据。
      3. 优点:低耦合。缺点:依赖于MQ的可靠性。
    3. 监听binlog:
      1. 服务层操作数据库。
      2. 数据库把操作记录到binlog。
      3. canal这个中间件去监听binlog,通知ES。
      4. ES更新数据。
      5. 优点:完全解除耦合度。缺点:依赖于中间件canal和mysql。mysql压力增大。

异步通知的操作:

  1. 发送MQ:
    1. 采用topic交换机。
    2. 当进行新增和修改时,发送 id 给交换机,声明“新增”的路由键(routing key)。
    3. 当进行删除时,发送 id 给交换机,并声明“删除”的路由键(routing key)。
      1. 注:不发送整个数据,而是数据的 id,以减少信息传输的数据量。
  2. 监听MQ:
    1. 监听“新增”队列的监听器:对 ES 发送新增请求。
    2. 监听“删除”队列的监听器:对 ES 发送删除请求。

单体式项目:

示例,增的同步代码,在 Controller 层:

//    增
    @PostMapping()
    public User save(@RequestBody User user) throws IOException {
//        保存到mysql
        userService.save(user);
//        保存到mysql后,id已经有了,可以直接插入到ES
        esService.AddDocument(user);
        return user;
    }

 注:前端发来的数据 user 无 id,通过Mybatis Plus 插入到 mysql 数据库后 user 有 id,可以直接插入到 ES(不需要从 mysql 数据库查询得到 user 数据,再插入 ES)。

2. 查询 + 分页

示例,对“昵称”进行全文检索查询:

1. 创建一个配置类,注入一个 bean 方法,把向 ES 发送请求的 client 注入 IOC。

@Configuration
public class EsConfig {
    @Bean
    public RestHighLevelClient clien(){
        return new RestHighLevelClient(RestClient.builder(
                HttpHost.create("http://localhost:9200")
        ));
    }
}

2. POJO 中封装三个类:

收到前端的类 EsPageParams

@Data
public class EsPageParams {
    private String key;
    private Integer page;
    private Integer size;
}

发给前端的类 EsPageResult 

@Data
@NoArgsConstructor
@AllArgsConstructor
public class EsPageResult {
    private Long total;
    private List<User> users;
}

数据库的类 User 

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    @TableId(type = IdType.AUTO)
    private Long id; //ID
    private String username; //用户名
    private String password; //密码
    private String niCheng; //姓名
    private Integer gender;
    private String location;
    private String txImageName;
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
}

(如果 ES 和 mysql 数据库不一致,还需要一个 ES 类) 

3. Controller 层:接受请求,发送给 Service 层。

4. Service 层:对 user 索引表的 niCheng 字段进行检索,检索方式是倒排索引。最终结果返回给 Controller 层。

@Service
public class EsService {

    @Autowired
    private RestHighLevelClient client;

    @Autowired
    private UserService userService;

    public EsPageResult search(EsPageParams esPageParams) throws IOException {
//        1.准备request
        SearchRequest request = new SearchRequest("user");
//        2. 准备DSL
        String key = esPageParams.getKey();
        request.source().query(QueryBuilders.matchQuery("niCheng",key));
        int page = esPageParams.getPage();
        int size = esPageParams.getSize();
        request.source().from((page - 1) * size).size(size);
//        3. 发送请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);

//        4.解析响应
        return handleResponse(response);
    }

    private EsPageResult handleResponse(SearchResponse response){
        SearchHits searchHits = response.getHits();
        long total = searchHits.getTotalHits().value;
        System.out.println("共搜索到"+total+"条数据");
        SearchHit[] hits = searchHits.getHits();
        List<User> users = new ArrayList<>();
        for(SearchHit hit : hits){
            String json = hit.getSourceAsString();
            User user = JSON.parseObject(json, User.class);
            users.add(user);
        }
        return new EsPageResult(total, users);
    }

  • 26
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
实现搜索引擎一般需要以下步骤: 1. 数据库建表和数据导入:根据需要建立相应的数据库表,并导入数据。 2. Elasticsearch安装和配置:安装Elasticsearch,配置Elasticsearch集群,并将数据导入到Elasticsearch中。 3. Spring Boot和Vue.js项目搭建:使用Spring Boot和Vue.js框架搭建项目。 4. 搜索功能实现:使用Elasticsearch进行搜索功能的实现。 具体实现步骤如下: 1. 数据库建表和数据导入 根据需求建立相应的数据库表,并将数据导入到数据库中。这里以MySQL为例,建立一个books表: CREATE TABLE `books` ( `id` int NOT NULL AUTO_INCREMENT, `title` varchar(255) DEFAULT NULL, `author` varchar(255) DEFAULT NULL, `content` text, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 将数据导入到books表中: INSERT INTO `books` (`id`, `title`, `author`, `content`) VALUES (1, 'Java编程思想', 'Bruce Eckel', 'Java编程思想是一本Java入门书籍。'), (2, 'Spring Boot实战', 'Craig Walls', 'Spring Boot实战是一本介绍Spring Boot框架的书籍。'), (3, 'Vue.js实战', '梁灏', 'Vue.js实战是一本介绍Vue.js框架的书籍。'); 2. Elasticsearch安装和配置 安装Elasticsearch,配置Elasticsearch集群,并将数据导入到Elasticsearch中。这里以Elasticsearch 7.2.0为例,安装步骤如下: (1)下载Elasticsearch 官网下载地址:https://www.elastic.co/downloads/elasticsearch (2)解压并启动Elasticsearch 解压后进入bin目录,执行以下命令启动Elasticsearch: ./elasticsearch (3)安装中文分词器 Elasticsearch默认使用英文分词器,需要安装中文分词器,这里使用IK Analyzer中文分词器。IK Analyzer的GitHub地址为:https://github.com/medcl/elasticsearch-analysis-ik 下载IK Analyzer插件: wget https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.2.0/elasticsearch-analysis-ik-7.2.0.zip 将插件安装到Elasticsearch中: ./elasticsearch-plugin install file:///path/to/elasticsearch-analysis-ik-7.2.0.zip (4)将数据导入到Elasticsearch中 使用Elasticsearch的API将数据库中的数据导入到Elasticsearch中。 3. Spring Boot和Vue.js项目搭建 使用Spring Boot和Vue.js框架搭建项目,这里不再赘述。 4. 搜索功能实现 (1)在Spring Boot中使用Elasticsearch进行搜索 使用Spring Data Elasticsearch实现Elasticsearch的交互,具体步骤如下: 1. 在pom.xml中添加Spring Data Elasticsearch依赖: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency> 2. 在application.yml中配置Elasticsearchspring: data: elasticsearch: cluster-name: elasticsearch cluster-nodes: 127.0.0.1:9300 3. 创建一个Book实体类,并使用@Document注解标注该实体类对应的Elasticsearch索引和类型: @Document(indexName = "books", type = "book") public class Book { @Id private Long id; private String title; private String author; private String content; // getter和setter方法省略 } 4. 创建一个BookRepository接口,继承ElasticsearchRepository接口: public interface BookRepository extends ElasticsearchRepository<Book, Long> { } 5. 在BookService中实现搜索功能: @Service public class BookService { @Autowired private BookRepository bookRepository; public List<Book> search(String keyword) { QueryBuilder queryBuilder = QueryBuilders.multiMatchQuery(keyword, "title", "author", "content"); Iterable<Book> iterable = bookRepository.search(queryBuilder); List<Book> books = new ArrayList<>(); iterable.forEach(books::add); return books; } } (2)在Vue.js中调用搜索接口 使用axios库调用Spring Boot的接口,具体步骤如下: 1. 安装axios库: npm install axios --save 2. 在Vue.js中调用搜索接口: <script> import axios from 'axios'; export default { data() { return { keyword: '', books: [] } }, methods: { search() { axios.get('/api/search?keyword=' + this.keyword).then(response => { this.books = response.data; }).catch(error => { console.log(error); }); } } } </script> 以上就是使用Spring Boot和Vue.js实现Elasticsearch搜索引擎的步骤。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值