编程知识 cdmana.com

SpringBoot-Elasticsearch

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

依赖

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]

配置

server:
  port: 9099
  data:
    elasticsearch:
      cluster-name: elasticsearch
      # elasticsearch 节点
      cluster-nodes: 127.0.0.1:9300

模型

@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_FloatScaled_Float,日期,Date_Nanos,布尔值,二进制,Integer_RangeFloat_RangeLong_RangeDouble_RangeDate_RangeIp_ ,嵌套,IpTokenCount,过滤器,展平,Search_As_You_Type。请参阅Elasticsearch映射类型
    • format日期类型的pattern定义。必须为日期类型定义。format
    • store:标记原始字段值是否应存储在Elasticsearch中,默认值为false
    • analyzersearchAnalyzernormalizer用于指定自定义分析和正规化。
  • @GeoPoint:将字段标记为geo_point数据类型。如果字段是GeoPoint类的实例,则可以省略。

缓存服务

import org.springframework.stereotype.Repository;

@Repository
public interface CacheRepository<S, I extends Number> extendsElasticsearchRepository<Student, Integer>{
}

缓存控制器

@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的查询,有很多不同的方式,先介绍一些入门的查询方式

按照方法名查询

查询
1、从方法名查询创建
 关键字:AND
         OR
         Between
         LessThan 小
         GreaterTha
         Like 模糊
         IgnoreCase
         OrderBy 排序
         Asc 正序
         Desc 倒叙

缓存服务

/**
 * 模糊查询所有学生名称
 *
 * @param name 名称
 * @return
 */
List<Student> findAllByNameLike(String name);

控制器

/**
 * 根据名称模糊查询
 *
 * @return
 */
@GetMapping("selectAllByName")
public List<Student> selectAllByName(String name) {
    return cacheRepository.findAllByNameLike(name);
}

属性表达式查询

若 Student 含有 UserName 字段
例:
List<Student> findByUserName(String userName);
Resulting:
UserName可能会被拆分成 user 、name 两个字段,一定概率!!!
下划线字符视为保留字符,所以我们强烈建议您遵循标准的Java命名约定(即,在属性名称中不使用下划线,而使用驼峰大小写)。
即:List<Student> findBy_UserName(String userName);

特殊参数处理

    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等工具时可能会干扰本机映像编译。
 /**
  * 查询全部
  *
  * @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);
}
@Repository
public interface StudentRepository extends CacheRepository<Student, Integer> {

    /**
     * 模糊查询所有学生名称
     *
     * @param name 名称
     * @return
     */
    @Override
    List<Student> findAllByNameLike(String name);
}
@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基本上差不多,要是一起用怕是会蒙圈。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

版权声明
本文为[Shao Jie]所创,转载请带上原文链接,感谢
https://cloud.tencent.com/developer/article/1858560

Scroll to Top