Spring Boot
整合Elasticsearch
废话少说,直接开干
安装
下载一个elasticsearch
,这里我们准备的是elasticsearch-6.4.3.tar.gz
上传文件到服务器上/usr/local/elasticsearch/elasticsearch-6.4.3
解压
$ tar -zxvf elasticsearch-6.4.3.tar.gz
创建用户角色运行
$ useradd root-es
切换用户
$ su root-es
启动 进入到bin目录下
$ ./elasticsearch
请求检查
$ curl 127.0.0.1:9200
{
"name" : "TZwBB7T",
"cluster_name" : "elasticsearch",
"cluster_uuid" : "7EQkN-jPQyGp672BIG2rbQ",
"version" : {
"number" : "6.4.3",
"build_flavor" : "default",
"build_type" : "tar",
"build_hash" : "fe40335",
"build_date" : "2018-10-30T23:17:19.084789Z",
"build_snapshot" : false,
"lucene_version" : "7.4.0",
"minimum_wire_compatibility_version" : "5.6.0",
"minimum_index_compatibility_version" : "5.0.0"
},
"tagline" : "You Know, for Search"
}
这样显示就是成功了,但是通过ip port
的时候却没有办法访问:
$ curl 192.168.1.105:9200
curl: (7) Failed connect to 192.168.1.105:9200; 拒绝连接
这就很难受,最后发现需要修改config
中的配置
$ vim elasticsearch.yml
network.host: 0.0.0.0
重新启动
$ ./elasticsearch
又报错ERROR: bootstrap checks failed
编辑/etc/security/limits.conf,追加以下内容;
* soft nofile 65536
* hard nofile 65536
编辑 /etc/sysctl.conf,追加以下内容:
vm.max_map_count=655360
保存后,执行:
sysctl -p
重新启动,成功。
请求检查
$ curl 192.168.1.105:9200
{
"name" : "TZwBB7T",
"cluster_name" : "elasticsearch",
"cluster_uuid" : "7EQkN-jPQyGp672BIG2rbQ",
"version" : {
"number" : "6.4.3",
"build_flavor" : "default",
"build_type" : "tar",
"build_hash" : "fe40335",
"build_date" : "2018-10-30T23:17:19.084789Z",
"build_snapshot" : false,
"lucene_version" : "7.4.0",
"minimum_wire_compatibility_version" : "5.6.0",
"minimum_index_compatibility_version" : "5.0.0"
},
"tagline" : "You Know, for Search"
}
Springboot
整合elasticsearch
依赖
代码语言:javascript复制plugins {
id 'org.springframework.boot' version '2.1.11.RELEASE'
id 'io.spring.dependency-management' version '1.0.10.RELEASE'
id 'java'
}
group = 'top.lzmvlog'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '8'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
// 配置镜像仓库
maven { url 'https://maven.aliyun.com/repository/public/' }
// 优先本地仓库查找
mavenLocal()
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-elasticsearch'
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
test {
useJUnitPlatform()
}
对应版本
!!!这里需要注意得是整合得版本问题,elasticsearch-6.4.3
我这里整合得是SpringBoot 2.1.11.RELEASE
,具体版本对应:
Spring Data Release Train | Spring Data Elasticsearch | Elasticsearch | Spring Boot |
---|---|---|---|
2020.0.0[1] | 4.1.x[1] | 7.9.3 | 2.3.x[1] |
Neumann | 4.0.x | 7.6.2 | 2.3.x |
Moore | 3.2.x | 6.8.12 | 2.2.x |
Lovelace | 3.1.x | 6.2.2 | 2.1.x |
Kay[2] | 3.0.x[2] | 5.5.0 | 2.0.x[2] |
Ingalls[2] | 2.1.x[2] | 2.4.0 | 1.5.x[2] |
配置
代码语言:javascript复制server:
port: 9099
data:
elasticsearch:
cluster-name: elasticsearch
# elasticsearch 节点
cluster-nodes: 127.0.0.1:9300
模型
代码语言:javascript复制@Data
@Document(indexName = "student", type = "_doc")
public class Student implements Serializable {
/**
* id
*/
private Integer id;
/**
* 名称
*/
private String name;
/**
* 年龄
*/
private Integer age;
}
映射注释
@Document
:在类级别应用,以指示该类是映射到数据库的候选对象。最重要的属性是:indexName
:用于存储此实体的索引的名称。它可以包含SpEL
模板表达式,例如"log-#{T(java.time.LocalDate).now().toString()}"
type
:映射类型。如果未设置,则使用小写的类的简单名称。(从版本4.0开始不推荐使用)shards
:索引的分片数。replicas
:索引的副本数。refreshIntervall
:索引的刷新间隔。用于索引创建。默认值为*“ 1s”*。indexStoreType
:索引的索引存储类型。用于索引创建。默认值为*“ fs”*。createIndex
:标记是否在存储库引导中创建索引。默认值为true。请参见使用相应的映射自动创建索引versionType
:版本管理的配置。默认值为EXTERNAL。
@Id
:在字段级别应用,以标记用于标识目的的字段。@Transient
:默认情况下,存储或检索文档时,所有字段都映射到文档,此注释不包括该字段。@PersistenceConstructor
:标记从数据库实例化对象时要使用的给定构造函数,甚至是受保护的程序包。构造函数参数按名称映射到检索到的Document中的键值。@Field
:在字段级别应用并定义字段的属性,大多数属性映射到各自的Elasticsearch映射定义(以下列表不完整,请查看注释Javadoc以获得完整参考):name
:字段名称,因为它将在Elasticsearch
文档中表示,如果未设置,则使用Java字段名称。type
:字段类型,可以是以下类型之一:*文本,关键字,长整数,整数,短整数,字节,双精度,浮点型,Half_Float
,Scaled_Float
,日期,Date_Nanos
,布尔值,二进制,Integer_Range
,Float_Range
,Long_Range
,Double_Range
,Date_Range
,Ip_
,嵌套,Ip
,TokenCount
,过滤器,展平,Search_As_You_Type
。请参阅Elasticsearch映射类型format
和日期类型的pattern
定义。必须为日期类型定义。format
store
:标记原始字段值是否应存储在Elasticsearch
中,默认值为false。analyzer
,searchAnalyzer
,normalizer
用于指定自定义分析和正规化。
@GeoPoint
:将字段标记为geo_point数据类型。如果字段是GeoPoint
类的实例,则可以省略。
缓存服务
代码语言:javascript复制import org.springframework.stereotype.Repository;
@Repository
public interface CacheRepository<S, I extends Number> extendsElasticsearchRepository<Student, Integer>{
}
缓存控制器
代码语言:javascript复制@RestController
public class CacheController {
private final CacheRepository<Student, Integer> cacheRepository;
StudentController(CacheRepository<Student, Integer> cacheRepository) {
this.cacheRepository = cacheRepository;
}
/**
* 新增缓存
*
* @param student
* @return
*/
@PostMapping("save")
public R save(@RequestBody Student student) {
// 缓存 存放主健一致时 覆盖原因的值 可以用于修改
cacheRepository.save(student);
return new R(HttpStatus.OK.value());
}
/**
* 根据id查询缓存
*
* @return
*/
@GetMapping("selectById")
public Optional<Student> selectById(Integer id) {
return cacheRepository.findById(id);
}
/**
* 查询全部
*
* @return
*/
@GetMapping("select")
public Iterable<Student> select() {
return cacheRepository.findAll();
}
/**
* 删除全部
*
* @return
*/
@GetMapping("delete")
public R delete() {
cacheRepository.deleteAll();
return new R(HttpStatus.OK.value());
}
/**
* 删除
*
* @return
*/
@GetMapping("deleteById")
public R deleteById(Integer id) {
cacheRepository.deleteById(id);
return new R(HttpStatus.OK.value());
}
}
查询
关于Elasticsearch
的查询,有很多不同的方式,先介绍一些入门的查询方式
按照方法名查询
代码语言:javascript复制查询
1、从方法名查询创建
关键字:AND
OR
Between
LessThan 小
GreaterTha
Like 模糊
IgnoreCase
OrderBy 排序
Asc 正序
Desc 倒叙
缓存服务
代码语言:javascript复制/**
* 模糊查询所有学生名称
*
* @param name 名称
* @return
*/
List<Student> findAllByNameLike(String name);
控制器
代码语言:javascript复制/**
* 根据名称模糊查询
*
* @return
*/
@GetMapping("selectAllByName")
public List<Student> selectAllByName(String name) {
return cacheRepository.findAllByNameLike(name);
}
属性表达式查询
代码语言:javascript复制若 Student 含有 UserName 字段
例:
List<Student> findByUserName(String userName);
Resulting:
UserName可能会被拆分成 user 、name 两个字段,一定概率!!!
下划线字符视为保留字符,所以我们强烈建议您遵循标准的Java命名约定(即,在属性名称中不使用下划线,而使用驼峰大小写)。
即:List<Student> findBy_UserName(String userName);
特殊参数处理
代码语言:javascript复制 Pageable,Slice和Sort
注:
Pageable 可以用于返回分页信息
Slice 可以用于返回一个集合对象 Slice<Student> 并通过 hasNext() 方法判断是否具有下一个数据 从而进行下一次查询
Sort 排序
Sort sort = Sort.by("id").ascending().and(Sort.by("age").descending());
TypedSort<Student> student = Sort.sort(Student.class);
Sort sort = student.by(Student::getId).ascending().and(student.by(Student::getAge).descending());
TypedSort.by(…) 通过(通常)使用CGlib使用运行时代理,这在使用Graal VM Native等工具时可能会干扰本机映像编译。
代码语言:javascript复制 /**
* 查询全部
*
* @return
*/
@GetMapping("select")
public Iterable<Student> select() {
// 展示不支持 lambdas 表达式
// 倒叙查找
Sort sort = new Sort(Sort.Direction.DESC, "id");
return cacheRepository.findAll(sort);
}
/**
* 查询全部
*
* @return
*/
@GetMapping("selectPage")
public Page<Student> selectPage(Pageable pageable) {
return cacheRepository.findAll(pageable);
}
自定义缓存实现
实现在Spring Data Repositories
功能之上定义自己的抽象。
中间存储库接口用注释@NoRepositoryBean
。确保将注释添加到所有存储库接口,Spring Data
不应在运行时为其创建实例。
@NoRepositoryBean
public interface CacheRepository<S, I extends Number> extends ElasticsearchRepository<S, I> {
/**
* 接口类注解:
* @NoRepositoryBean
* 确保将注释添加到所有存储库接口,Spring Data不应在运行时为其创建实例。
*
* Resulting:
* springboot不会为其自动创建 bean
*
* Parameter 0 of constructor in top.lzmvlog.elasticsearchdemo.controller.StudentController required a bean of type
* 'top.lzmvlog.elasticsearchdemo.repository.CacheRepository' that could not be found.
*/
/**
* 模糊查询所有学生名称
*
* @param name 名称
* @return
*/
List<Student> findAllByNameLike(String name);
}
代码语言:javascript复制@Repository
public interface StudentRepository extends CacheRepository<Student, Integer> {
/**
* 模糊查询所有学生名称
*
* @param name 名称
* @return
*/
@Override
List<Student> findAllByNameLike(String name);
}
代码语言:javascript复制@RestController
public class StudentController {
private final CacheRepository<Student, Integer> cacheRepository;
StudentController(CacheRepository<Student, Integer> cacheRepository) {
this.cacheRepository = cacheRepository;
}
/**
* 根据名称模糊查询
*
* @return
*/
@GetMapping("selectAllByName")
public List<Student> selectAllByName(String name) {
return cacheRepository.findAllByNameLike(name);
}
}
Elasticsearch
的查询和Sping data Jpa
基本上差不多,要是一起用怕是会蒙圈。