目前公司的一个老项目,查询贼慢,需要想办法提升一下速度,于是就想到了ES,现在尝试一下将ES整合到项目中来提升检索效率。
ES是基于倒排索引实现的,倒排索引中一个表相当于一个索引,表中的每条记录都是一个文档(JSON数据),系统会先对字段数据进行分词,然后给词条建立索引,并映射到文档id。在查询的时候根据输入进行分词,然后根据词条走索引查询文档id,再根据文档id查询文档并放入结果集,最后将结果集返回。
一般来说,ES算是难度较高的一个技术栈,需要中高级才能熟练驾驭,新手入门比较难,因而我选中了对新手更加友好的easy-es,其在ES的基础上做了封装,使得使用起来和MybatisPlus很像,简单上手。
开始使用easy-es之前,建议先看一下避坑指南
ES官网
按照官方推荐下载7.x的ES,我下载了和官方demo一样的7.14.0版本。
输入7.14.0搜索该版本并下载
下载完成之后解压,并去到bin目录,双击elasticsearch.bat文件启动elasticsearch。
<dependency>
<groupId>org.dromara.easy-esgroupId>
<artifactId>easy-es-boot-starterartifactId>
<version>Latest Versionversion>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
<exclusions>
<exclusion>
<groupId>org.elasticsearch.clientgroupId>
<artifactId>elasticsearch-rest-high-level-clientartifactId>
exclusion>
<exclusion>
<groupId>org.elasticsearchgroupId>
<artifactId>elasticsearchartifactId>
exclusion>
exclusions>
dependency>
<dependency>
<groupId>org.elasticsearch.clientgroupId>
<artifactId>elasticsearch-rest-high-level-clientartifactId>
<version>7.14.0version>
dependency>
<dependency>
<groupId>org.elasticsearchgroupId>
<artifactId>elasticsearchartifactId>
<version>7.14.0version>
dependency>
easy-es:
enable: true #默认为true,若为false则认为不启用本框架
address: 127.0.0.1:9200 # es的连接地址,必须含端口 若为集群,则可以用逗号隔开 例如:127.0.0.1:9200,127.0.0.2:9200
# username: elastic #若无 则可省略此行配置。因为刚下载的ES默认不用账号密码登录,所以注掉
# password: WG7WVmuNMtM4GwNYkyWH #若无 则可省略此行配置
@EsMapperScan("org.jeecg.modules.test.esmapper")
@SpringBootApplication
public class JeecgSystemApplication extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(JeecgSystemApplication.class);
}
public static void main(String[] args) throws UnknownHostException {
ConfigurableApplicationContext application = SpringApplication.run(JeecgSystemApplication.class, args);
}
}
package org.jeecg.modules.message.entity;
import org.dromara.easyes.annotation.IndexField;
import org.dromara.easyes.annotation.IndexName;
import org.dromara.easyes.annotation.rely.Analyzer;
import org.dromara.easyes.annotation.rely.FieldType;
import org.jeecg.common.aspect.annotation.Dict;
import org.jeecg.common.system.base.entity.JeecgEntity;
import org.jeecgframework.poi.excel.annotation.Excel;
import org.springframework.format.annotation.DateTimeFormat;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
@Data
@IndexName
public class SysMessage{
/** ID */
@TableId(type = IdType.ASSIGN_ID)
private java.lang.String id;
/**推送内容*/
private java.lang.String esContent;
/**推送所需参数Json格式*/
private java.lang.String esParam;
/**接收人*/
private java.lang.String esReceiver;
/**推送失败原因*/
private java.lang.String esResult;
/**发送次数*/
private java.lang.Integer esSendNum;
/**推送状态 0未推送 1推送成功 2推送失败*/
private java.lang.String esSendStatus;
/**推送时间*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private java.util.Date esSendTime;
/**消息标题*/
private java.lang.String esTitle;
/**推送方式:1短信 2邮件 3微信*/
private java.lang.String esType;
/**备注*/
private java.lang.String remark;
/** 创建人 */
private java.lang.String createBy;
/** 创建时间 */
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private java.util.Date createTime;
/** 更新人 */
private java.lang.String updateBy;
/** 更新时间 */
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private java.util.Date updateTime;
}
package org.jeecg.modules.test.esmapper;
import org.dromara.easyes.core.core.BaseEsMapper;
import org.jeecg.modules.message.entity.SysMessage;
public interface DocumentMapper extends BaseEsMapper<SysMessage> {
}
@Resource
private DocumentMapper documentMapper;
@GetMapping("/createIndex")
@ApiOperation("创建索引")
public Object createIndex(String a){
Boolean index = documentMapper.createIndex();
System.out.println(index);
return index;
}
@GetMapping("/createDoc")
@ApiOperation("创建文档")
public Object createDoc(String a,String b){
SysMessage sysMessage=new SysMessage();
sysMessage.setEsContent(a);
sysMessage.setEsTitle(b);
sysMessage.setEsReceiver("系统管理员");
sysMessage.setEsSendNum(10);
Integer insert = documentMapper.insert(sysMessage);
return insert;
}
@GetMapping("/updateDoc")
@ApiOperation("updateDoc")
public Object updateDoc(String a){
LambdaEsUpdateWrapper<SysMessage> wrapper=new LambdaEsUpdateWrapper<>();
wrapper.eq(SysMessage::getEsContent,a)
.set(SysMessage::getEsContent,"更改后的标题");
Integer update = documentMapper.update(null, wrapper);
return update;
}
@GetMapping("/getDoc")
@ApiOperation("查询文档")
public Object getDoc(String a){
List<SysMessage> list = EsWrappers.lambdaChainQuery(documentMapper).like(SysMessage::getEsContent, a).list();
return list;
}
删除的语法比更新还简单,也是创建一个esupdatewrapper,用eq、in等筛选,然后调用delete方法就可以了,就不演示了。
Springboot整合ES最大可能遇到的问题就是ES版本的问题,也就是依赖冲突。如果依赖冲突,在项目启动的时候会有一个ERROR日志提醒,看到了就想办法去掉原来带着的ES依赖或者更改依赖版本为7.14.0
关于ES的数据更新,就要去了解ES同步数据库相关的知识了。
想要了解easy-es的更多特性,建议去看easy-es的官网文档。