Elasticsearch
Elasticsearch 简介
- 一个分布式的、Restful 风格的搜索引擎
- 支持对各种类型的数据的检索
- 搜索速度快,可以提供实时的搜索服务
- 便于水平扩展,每秒可以处理 PB 级海量数据
Elasticsearch 术语
- 索引、类型、文档、字段
- 集群、节点、分片、副本
索引可以理解为一个数据库
类型为一张表
文档为一条数据,通常为 JSON 结果
字段为表中的列
在 ES6 以后,逐渐废弃上面的类型,ES7(本文使用)彻底废除,由索引逐渐代替其功能
Elasticsearch 和 SpringBoot 是有版本对应的,点击查看
下载Elasticsearch,在使用 ES 之前,还需要装一个ik 分词器,下载好之后,将其解压至 ES 的 plugins 文件夹中的 ik 文件夹(无则创建)
在使用 ES 之前,我们最好简单更改一下其配置,在 config 目录下,找到 elasticsearch.yml,进行如下更改
# 集群的名字 随意
cluster.name: nowcoder
# ES数据存储路径
path.data: /home/gas/桌面/elasticsearch-7.12.0/data
# 日志
path.logs: /home/gas/桌面/elasticsearch-7.12.0/logs
然后执行 bin 目录下的 elasticsearch 文件即可
SpringBoot 使用 Elasticsearch
1. Maven 引入
<!-- elasticsearch -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
2. yml 配置
spring:
elasticsearch:
rest:
username: nowcoder # 填写上面自己配置的
uris: 127.0.0.1:9200 # es的ip:port
3. 配置 ES 实体类
直接用现有的实体类就好,并不冲突
//indexName:索引的名称
//shards:分片
//replicas:副本
//type:7.x不用写
@Document(indexName = "discusspost", shards = 6, replicas = 3)
public class DiscussPost {
//声明ID
@Id
private int id;
//声明类型
@Field(type = FieldType.Integer)
private int userId;
//后面两个是使用的分词器的名字,没什么必要无须更改,前面是存储数据时使用的解析器(存储时尽可能拆分出更多的词语进行存储),后面是搜索时使用的解析器(搜索时无须过分分词)
@Field(type = FieldType.Text, analyzer = "ik_max_word", searchAnalyzer = "ik_smart")
private String title;
@Field(type = FieldType.Text, analyzer = "ik_max_word", searchAnalyzer = "ik_smart")
private String content;
//name:字段在es中的名称
@Field(name = "type",type = FieldType.Integer)
private int type;
@Field(type = FieldType.Integer)
private int status;
@Field(name = "createTime",type = FieldType.Date)
private Date createTime;
@Field(type = FieldType.Integer)
private int commentCount;
@Field(name = "score",positiveScoreImpact = false,type = FieldType.Double)
private double score;
}
4. 创建一个操作 ES 的类
@Repository //<处理的对象,对象的主键类型>
public interface DiscussPostRepository extends ElasticsearchRepository<DiscussPost,Integer> {
//高亮
@Highlight(
fields = {
@HighlightField(name = "title"),
@HighlightField(name = "content")
},parameters = @HighlightParameters(
preTags = "<em>",
postTags = "</em>"
))
//Pageable包含了排序功能,如果你只需要排序,则替换成Sort sort即可,注意:Pageable和Sort不能同时存在
List<SearchHit<DiscussPost>> findDiscussPostByTitleLikeOrContentLike(String title,String content,Pageable pageable);
//注意,方法的名称findDiscussPostByTitleLikeOrContentLike可不是乱写的,是用含义的,底层会根据方法名称去构建搜索语句
//当然,也可以用@Query注解自定义搜索语句,下面是官方文档的声明
//https://docs.spring.io/spring-data/elasticsearch/docs/4.1.8/reference/html/#elasticsearch.query-methods
}
5. 实际操作演示
@Autowired
private DiscussPostRepository discussPostRepository;
//保存数据,这里是从数据库中读取了一条DiscussPost类型的数据存入es中
discussPostRepository.save(discussPostMapper.selectDiscussPostById(230));
//批量存储
discussPostRepository.saveAll(discussPostMapper.selectDiscussPosts(101, 0, 100,0));
//更新数据
DiscussPost discussPost = discussPostMapper.selectDiscussPostById(231);
discussPost.setContent("我是新人,使劲灌水");
discussPostRepository.save(discussPost);
//根据ID删除
discussPostRepository.deleteById(231);
//删除所有
discussPostRepository.deleteAll();
//搜索
public void Select(){
Sort sort = Sort.by("score").descending()
.and(Sort.by("type").descending())
.and(Sort.by("createTime").descending());
List<SearchHit<DiscussPost>> post = discussPostRepository
//分页数据第1页,10条数据,排序
.findDiscussPostByTitleLikeOrContentLike("压力数据", "压力",PageRequest.of(1,10,sort));
post.forEach(res-> {
System.out.println("查询结果:" + res);
});
}
参考:
官方文档:https://docs.spring.io/spring-data/elasticsearch/docs/4.1.8/reference/html/#repositories