SpringBoot 使用 Elasticsearch搜索引擎
SpringBoot 使用 ElasticSearch 6.x搜索引擎
一、介绍
Elasticsearch (ES)是一个基于Lucene构建的开源、分布式、RESTful 接口全文搜索引擎。Elasticsearch 还是一个分布式文档数据库,其中每个字段均是被索引的数据且可被搜索,它能够扩展至数以百计的服务器存储以及处理PB级的数据。它可以在很短的时间内在储、搜索和分析大量的数据。它通常作为具有复杂搜索场景情况下的核心发动机。
Elasticsearch就是为高可用和可扩展而生的。可以通过购置性能更强的服务器来完成。
二、Elasticsearch优势
-
横向可扩展性:只需要增加台服务器,做一点儿配置,启动一下Elasticsearch就可以并入集群。
-
分片机制提供更好的分布性:同一个索引分成多个分片(sharding), 这点类似于HDFS的块机制;分而治之的方式可提升处理效率。
-
高可用:提供复制( replica) 机制,一个分片可以设置多个复制,使得某台服务器在宕机的情况下,集群仍旧可以照常运行,并会把服务器宕机丢失的数据信息复制恢复到其他可用节点上。
口使用简单:共需一条命令就可以下载文件,然后很快就能搭建一一个站内搜索引擎。
三、Elasticsearch存储结构
Elasticsearch是文件存储,Elasticsearch是面向文档型数据库,一条数据在这里就是一个文档,用JSON作为文档序列化的格式,比如下面这条用户数据
{
"name" : "哈哈哈",
"sex" : 男,
"age" : 10
}
- 1
- 2
- 3
- 4
- 5
关系数据库 ⇒ 数据库 ⇒ 表 ⇒ 行 ⇒ 列(Columns)
Elasticsearch ⇒ 索引(Index) ⇒ 类型(type) ⇒ 文档(Docments) ⇒ 字段(Fields)
四、Elasticsearch版本控制
- 版本控制
为了保证数据再多线程操作下的准确性 - 悲观锁和乐观锁
悲观锁:假设会发生并发冲突,屏蔽一切可能违反数据准确性的操作
悲观锁:假设不会发生并发冲突,只在提交操作是检查是否违反数据完整性。 - 内部版本控制和外部版本控制
内部版本控制:_version自增长,修改数据后,_version会自动的加1
外部版本控制:为了保持_version与外部版本控制的数值一致
五、环境搭建
Es的环境搭建,在我博客中有介绍,可参考:
https://blog.csdn.net/qq_43692950/article/details/107689309
六、SpringBoot集成Elasticsearch
1. pom
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
- 1
- 2
- 3
- 4
2. application.properties
#elasticsearch
spring.data.elasticsearch.cluster-name=elasticsearch
#集群
#spring.data.elasticsearch.cluster-nodes=192.168.2.112:9300,192.168.2.139:9300,192.168.2.133:9300
#单机
spring.data.elasticsearch.cluster-nodes=localhost:9300
spring.data.elasticsearch.repositories.enabled=true
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
3. Entity
@Document(indexName = "detection",type = "info") //索引名和类型
@Data
public class TakeEntity implements Serializable {
@Id
private long id;
@Field(type = FieldType.text, analyzer = "ik_smart", searchAnalyzer = "ik_smart") //使用ik中文分词器,ik的环境需要配置
private String deviceid;
@Field
private String imgpath;
@Field
private long time;
@Field
private String age;
@Field
private String gender;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
4. Repository
@Repository
public interface TakeFaceRepository extends ElasticsearchRepository<TakeEntity, Long> {
}
- 1
- 2
- 3
5. Service
public interface DemoService {
boolean save(TakeEntity takeFace);
Iterable<TakeEntity> findall();
void search();
boolean delete();
void update();
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
6. Impl
@Service
public class DemoServiceImpl implements DemoService {
@Autowired
TakeFaceRepository takeFaceRepository;
/*
添加数据
*/
@Override
public boolean save(TakeEntity takeFace) {
try {
//添加单条数据
takeFaceRepository.save(takeFace);
//添加多条数据
List<TakeEntity> list = new ArrayList<>();
list.add(takeFace);
list.add(takeFace);
list.add(takeFace);
takeFaceRepository.saveAll(list);
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
/*
查询数据 find
*/
@Override
public Iterable<TakeEntity> findall() {
//查询全部
Iterable<TakeEntity> all = takeFaceRepository.findAll();
//排序
takeFaceRepository.findAll(Sort.by(Sort.Direction.DESC, "time"));
//分页查询
Pageable pageable1 = PageRequest.of(1, 20);
//分页加排序
Pageable pageable = new PageRequest(1, 20, Sort.by(Sort.Direction.DESC, "time"));
Pageable pageable2 = PageRequest.of(1, 20, Sort.by(Sort.Direction.DESC, "time"));
Pageable pageable3 = PageRequest.of(1, 20, Sort.Direction.DESC, "time");
takeFaceRepository.findAll(pageable);
//根据id查询多个
List<Long> longs = new ArrayList<>();
longs.add(1234L);
takeFaceRepository.findAllById(longs);
return all;
}
/*
条件查询
*/
public void search() {
//精确查询 =
QueryBuilder queryBuilder = QueryBuilders.termQuery("info", "abc");
//精确查询 多个 in
QueryBuilder queryBuilder1 = QueryBuilders.termsQuery("info", "abc", "asd");
//模糊匹配
QueryBuilder queryBuilder2 = QueryBuilders.matchQuery("info", "ab");
//模糊匹配 多个
QueryBuilder queryBuilder3 = QueryBuilders.multiMatchQuery("info", "ab", "tc");
//全部数据
QueryBuilder queryBuilder4 = QueryBuilders.matchAllQuery();
//多条件构建BoolQueryBuilder
BoolQueryBuilder queryBuilder5 = QueryBuilders.boolQuery();
//并且 and
queryBuilder5.must(QueryBuilders.termQuery("info", "abc"));
queryBuilder5.must(QueryBuilders.termQuery("gender", "18"));
//或者 or
queryBuilder5.should(QueryBuilders.termQuery("info", "azs"));
queryBuilder5.should(QueryBuilders.termQuery("info", "azs1"));
//不等于
queryBuilder5.mustNot(QueryBuilders.termQuery("gender", "19"));
//过滤数据
queryBuilder5.filter(QueryBuilders.matchQuery("info", "ab"));
//范围查询
/*
gt 大于 >
gte 大于等于 >=
lt 小于 <
lte 小于等于 <=
*/
queryBuilder5.filter(new RangeQueryBuilder("age").gt(10).lte(50));
//使用分词器
queryBuilder5.must(QueryBuilders.matchQuery("info","abc").analyzer("ik_max_word"));
queryBuilder5.must(QueryBuilders.matchQuery("info","abc1").analyzer("ik_smart"));
//构建分页
Pageable pageable = PageRequest.of(1, 20);
//多场景下复杂条件
SearchQuery search = new NativeSearchQueryBuilder()
.withQuery(queryBuilder4)
.withPageable(pageable)
.withSort(SortBuilders.fieldSort("age").order(SortOrder.DESC))
.build();
takeFaceRepository.search(search);
takeFaceRepository.search(queryBuilder);
takeFaceRepository.search(queryBuilder5);
//分页查询
takeFaceRepository.search(queryBuilder, pageable);
}
/*
删除
*/
@Override
public boolean delete() {
try {
//删除全部数据
takeFaceRepository.deleteAll();
//根据id
takeFaceRepository.deleteById(1L);
//根据条件
TakeEntity takeEntity = new TakeEntity();
takeEntity.setInfo("abc");
takeFaceRepository.delete(takeEntity);
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
/*
修改数据,直接save保存
*/
@Override
public void update(){
TakeEntity entity = new TakeEntity();
entity.setId(10);
entity.setInfo("afg");
takeFaceRepository.save(entity);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
七、Kibana基本使用
Kibana es的客户端工具,安装可参考:
https://blog.csdn.net/qq_43692950/article/details/107713161
- 创建索引
PUT /testindex
- 1
- 查询索引
GET /testindex
- 1
- 添加文档
/索引名称/类型/id
PUT /testindex/user/2
{
"name":"abc",
"sex":2,
"age":18
}
- 1
- 2
- 3
- 4
- 5
- 6
- 根据id查询文档
GET /testindex/user/1
- 1
- 查询全部
GET /testindex/_search
- 1
GET /testindex/user/_search
- 1
- 查询多个id分别为1、2
GET /testindex/user/_mget
{
"ids":["1","2"]
}
- 1
- 2
- 3
- 4
- 精确查询
GET /testindex/user/_search
{
"query": {
"term": {
"name": "abc"
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 模糊查询
GET /testindex/user/_search
{
"from": 1,
"size": 2,
"query": {
"match": {
"name": "abc"
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 删除索引
DELETE /testindex
- 1
文章来源: blog.csdn.net,作者:小毕超,版权归原作者所有,如需转载,请联系作者。
原文链接:blog.csdn.net/qq_43692950/article/details/107443280
- 点赞
- 收藏
- 关注作者
评论(0)