20. Easy-es操作ElasticSearch

esay es官网 https://easy-es.cn/
源码:
链接:https://pan.baidu.com/s/1kZ4v4Of4MhHs7NKSVBOQNA
提取码:1111

1.需求

1.app端搜索,高亮显示
2.发表文章后新增索引
20. Easy-es操作ElasticSearch_第1张图片

2.创建search微服务

2.1 创建ruoyi-api-search

20. Easy-es操作ElasticSearch_第2张图片
pom:

 <dependencies>
        <dependency>
            <groupId>com.ruoyigroupId>
            <artifactId>ruoyi-common-elasticsearchartifactId>
        dependency>
        <dependency>
            <groupId>cn.easy-esgroupId>
            <artifactId>easy-es-annotationartifactId>
            <version>1.0.2version>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-data-mongodbartifactId>
        dependency>
    dependencies>

参考映射创建实体类:

{
  "mappings":{
    "properties":{
      "id":{
        "type":"long"
      },
      "publishTime":{
        "type":"date"
      },
      "layout":{
        "type":"integer"
      },
      "images":{
        "type":"keyword",
        "index": false
      },
      "staticUrl":{
        "type":"keyword",
        "index": false
      },
      "authorId": {
        "type": "long"
      },
      "authorName": {
        "type": "text"
      },
      "title":{
        "type":"text",
        "analyzer":"ik_smart"
      },
      "content":{
        "type":"text",
        "analyzer":"ik_smart"
      }
    }
  }
}

一个类就够了:SearchArticleVo:
注意,title和content需要ik分词处理。title被搜索出来后,点击进入下一个界面会被作为参数传递,高亮的html标记被加入后无法通过地址栏传递,所以需要使用h_title作为高亮显示,注意注解中title和h_title的配置。映射后,高亮处理的title值会被映射到h_title,普通title不会被映射,即h_title为空。参见getH_title

package com.ruoyi.search.domain;

import cn.easyes.annotation.HighLight;
import cn.easyes.annotation.IndexField;
import cn.easyes.annotation.IndexId;
import cn.easyes.annotation.IndexName;
import cn.easyes.common.constants.Analyzer;
import cn.easyes.common.enums.FieldType;
import cn.easyes.common.enums.IdType;

import cn.easyes.common.utils.StringUtils;
import lombok.Data;

import java.io.Serializable;
import java.util.Date;

@Data
@IndexName
public class SearchArticleVo implements Serializable {

    // 文章id
    @IndexId(type = IdType.CUSTOMIZE)
    private Long id;
    // 文章标题
    @HighLight(mappingField = "h_title",preTag = "",postTag = "")
    @IndexField(fieldType = FieldType.TEXT, analyzer = Analyzer.IK_SMART, searchAnalyzer = Analyzer.IK_MAX_WORD)
    private String title;
    // 文章发布时间
    @IndexField(fieldType = FieldType.DATE)
    private Date publishTime;
    // 文章布局
    @IndexField(fieldType = FieldType.INTEGER)
    private Integer layout;
    // 封面
    @IndexField(fieldType = FieldType.KEYWORD)
    private String images;
    // 作者id
    @IndexField(fieldType = FieldType.LONG)
    private Long authorId;
    // 作者名词
    @IndexField(fieldType = FieldType.TEXT)
    private String authorName;
    //静态url
    @IndexField(fieldType = FieldType.KEYWORD)
    private String staticUrl;
    //文章内容
    @IndexField(fieldType = FieldType.TEXT, analyzer = Analyzer.IK_SMART, searchAnalyzer = Analyzer.IK_MAX_WORD)
    private String content;

    @IndexField(exist = false)
    private String h_title;

    public String getH_title() {
        return StringUtils.isBlank(this.h_title) ? this.title : h_title;
    }
}

2.2 创建ruoyi-search微服务

20. Easy-es操作ElasticSearch_第3张图片

application-common.yml增加easy-es配置

--- # elasticsearch 功能配置
# 文档地址: https://www.easy-es.cn/
# 更改包名需要去 EasyEsConfiguration 修改包扫描(后续版本支持配置文件读取)
easy-es:
  banner: true
  # 是否开启EE自动配置
  enable: true
  # es连接地址+端口 格式必须为ip:port,如果是集群则可用逗号隔开
  address : 192.168.0.80:9200
  # 默认为http
  schema: http
  # 注意ES建议使用账号认证 不使用会报警告日志
  #如果无账号密码则可不配置此行
  #username:
  #如果无账号密码则可不配置此行
  #password:
  # 心跳策略时间 单位:ms
  keep-alive-millis: 18000
  # 连接超时时间 单位:ms
  connectTimeout: 5000
  # 通信超时时间 单位:ms
  socketTimeout: 5000
  # 请求超时时间 单位:ms
  requestTimeout: 5000
  # 连接请求超时时间 单位:ms
  connectionRequestTimeout: 5000
  # 最大连接数 单位:个
  maxConnTotal: 100
  # 最大连接路由数 单位:个
  maxConnPerRoute: 100
  global-config:
    # 开启控制台打印通过本框架生成的DSL语句,默认为开启,测试稳定后的生产环境建议关闭,以提升少量性能
    print-dsl: true
    # 异步处理索引是否阻塞主线程 默认阻塞 数据量过大时调整为非阻塞异步进行 项目启动更快
    asyncProcessIndexBlocking: true
    db-config:
      # 是否开启下划线转驼峰 默认为false
      map-underscore-to-camel-case: true
      # id生成策略 customize为自定义,id值由用户生成,比如取MySQL中的数据id,如缺省此项配置,则id默认策略为es自动生成
      id-type: customize
      # 字段更新策略 默认为not_null
      field-strategy: not_null
      # 默认开启,查询若指定了size超过1w条时也会自动开启,开启后查询所有匹配数据,若不开启,会导致无法获取数据总条数,其它功能不受影响.
      enable-track-total-hits: true
      # 数据刷新策略,默认为不刷新
      refresh-policy: immediate
      # 是否全局开启must查询类型转换为filter查询类型 默认为false不转换
      enable-must2-filter: false

上面说的es mapper具体配置类为:
20. Easy-es操作ElasticSearch_第4张图片
所以在微服务中创建mapper的位置要符合配置类:
20. Easy-es操作ElasticSearch_第5张图片
由于使用了esay es,所以操作变得非常简单,没有定义service,直接在controller中完成即可:
init为初始化,postman执行一次即可。
search为搜索方法。注意条件:
PublishTime

package com.ruoyi.search.controller;

import cn.easyes.core.biz.PageInfo;
import cn.easyes.core.conditions.LambdaEsQueryWrapper;
import com.ruoyi.common.dtos.ResponseResult;
import com.ruoyi.common.enums.AppHttpCodeEnum;
import com.ruoyi.common.satoken.utils.LoginHelper;
import com.ruoyi.search.domain.SearchArticleModel;
import com.ruoyi.search.domain.SearchArticleVo;
import com.ruoyi.search.domain.UserSearchDto;
import com.ruoyi.search.esmapper.SearchArticleMapper;
import com.ruoyi.search.mapper.ApArticleMapper;
import com.ruoyi.search.service.ApUserSearchService;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@ConditionalOnProperty(value = "easy-es.enable", havingValue = "true")
@RestController
@RequestMapping
@RequiredArgsConstructor
public class ArticleSearchController {

    private final ApArticleMapper apArticleMapper;

    private final SearchArticleMapper searchArticleMapper;

    private final ApUserSearchService apUserSearchService;

    @PostMapping("/api/v1/article/search/search")
    public ResponseResult search(@RequestBody UserSearchDto dto) throws IOException {
        //todo 1.校验参数
        if(dto == null || StringUtils.isBlank(dto.getSearchWords())){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }


        //异步调用 保存搜索记录
        //Long userId = LoginHelper.getUserId();
        //if(userId != null){
            apUserSearchService.insert(dto.getSearchWords(), 0L);
        //}



        //todo 2.1 封装关键字搜索条件,小于min_behot_time
        LambdaEsQueryWrapper<SearchArticleVo> wrapper = new LambdaEsQueryWrapper<>();
        wrapper
            .lt(SearchArticleVo::getPublishTime,dto.getMinBehotTime())
            .and(w->w.like(SearchArticleVo::getTitle, dto.getSearchWords()).or().like(SearchArticleVo::getContent,dto.getSearchWords()));

        //todo 2.2. 分页查询
        //wrapper.size(dto.getPageSize());
        wrapper.orderByDesc(SearchArticleVo::getId);
        PageInfo<SearchArticleVo> searchArticleVoPageInfo = searchArticleMapper.pageQuery(wrapper, 0, dto.getPageSize());
        return ResponseResult.okResult(searchArticleVoPageInfo.getList());
    }

    @GetMapping("/api/v1/article/search/init")
    public ResponseResult init() throws IOException {
        //1.查询所有符合条件的文章数据
        List<SearchArticleVo> searchArticleVos = apArticleMapper.loadArticleList();

        for (SearchArticleVo searchArticleVo : searchArticleVos) {
            searchArticleMapper.insert(searchArticleVo);
        }
        return ResponseResult.okResult(200,"初始化成功!");
    }
}

3.创建文章后新增索引

search微服务需要引入kafka依赖:

        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-starter-stream-kafkaartifactId>
        dependency>

article中创建kafka生产者:
20. Easy-es操作ElasticSearch_第6张图片

buildArticleToMinIO方法中调用生产者发消息
20. Easy-es操作ElasticSearch_第7张图片
search中创建消费者,新增索引:
20. Easy-es操作ElasticSearch_第8张图片
其他还有一些mongo的代码,用于处理搜索记录和搜索自动提示,和原教程源码基本一致, 不再赘述。

你可能感兴趣的:(elasticsearch,大数据,搜索引擎)