美文网首页Elasticsearch SpringBoot
Elasticsearch与SpringBoot进行集成(未完)

Elasticsearch与SpringBoot进行集成(未完)

作者: 意识流丶 | 来源:发表于2018-12-29 15:02 被阅读8次

    Elasticsearch具体版本强依赖性

    Elasticsearch以及其周边的相关平台都是强版本依赖的,升级过程也需要升级其他相关组件。
    目前Elasticsearch的6.x相当于3.x。之所以从2一跃跳到6,Elastic体系内还有KibanaLogstashBeats等产品。为了统一各产品版本,所以直接将Elasticsearch的版本从2提升到6 ,6.x版本提供了许多新的特性,并且基于Lucene7.x

    性能方面:

    1.磁盘空间可以节省近一半
    2.索引时间减少近50%
    3.查询性能提升近30%
    4.支持IPV6

    性能的具体数据可以查看Elasticsearch性能监控。性能的提升主要是Lucene6版本之后的很多底层结构的优化。Lucene6使用Block K-D trees数据结构来构建索引。BKD Trees是一种可以动态扩展的KD-tree结构。

    想了解BKD Trees可以参考:

    https://users.cs.duke.edu/~pankaj/publications/papers/bkd-sstd.pdf

    Elasticsearch也是一种数据库,属于非关系型数据库,不需要自己建库建表

    与SpringBoot进行集成

    实体类:

    @Data
    @Document(indexName = "province", type = "city")
    public class City implements Serializable {
        @Id
        @Field(fielddata = true)
        private Long id;
        private String score;
        private String name;
        private String description;
    }
    

    加上@Id注解后,在Elasticsearch里对应的该列就是主键了,在查询时就可以直接用主键查询

    相关代码说明:

    @Document源码

    @Persistent
    @Inherited
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.TYPE})
    public @interface Document {
        String indexName();
        String type() default "";
        boolean useServerConfiguration() default false;
        short shards() default 5;
        short replicas() default 1;
        String refreshInterval() default "1s";
        String indexStoreType() default "fs";
        boolean createIndex() default true;
    }
    

    indexName():索引库的名称,建议以项目的名称命名,类似于关系型数据库中数据库
    type():类型,建议以实体的名称命名,类似于关系型数据库中数据库表
    useServerConfiguration():是否使用服务器配置
    shards():默认分区数
    replicas():每个分区默认的备份数
    refreshInterval():刷新间隔
    indexStoreType():索引文件存储类型
    createIndex():是否创建索引

    @Field源码

    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.FIELD})
    @Documented
    @Inherited
    public @interface Field {
        FieldType type() default FieldType.Auto;
        boolean index() default true;
        DateFormat format() default DateFormat.none;
        String pattern() default "";
        boolean store() default false;
        boolean fielddata() default false;
        String searchAnalyzer() default "";
        String analyzer() default "";
        String normalizer() default "";
        String[] ignoreFields() default {};
        boolean includeInParent() default false;
        String[] copyTo() default {};
    }
    

    type():类型,默认自动检测,也可以根据实际情况设置
    index():原来的analyzed/not_analyzed/no变为只接受boolean值。分别代替not_analyzed/no
    format():时间类型的格式化
    store():是否存储原文
    searchAnalyzer():指定字段搜索时使用的分词器
    ignoreFields():忽略某个字段

    注:因为Elasticsearch6.x中的Mapping改变,原有的@Field(type = FieldType.string)类型的索引映射需要替换成@Field(type = FieldType.Keyword)或者@Field(type = FieldType.Text)。 要精确搜索就用Keyword,否则用Text。如果不需要通过该字段进行查询,则index设置false即可。

    可能出现的报错:

    Caused by: java.lang.IllegalArgumentException: mapper [xx] of different type, current_type [xxx], merged_type [xxx]
    

    因为索引已经存在了,创建索引时不会覆盖原有的,所以删除原有的就不会报错了

    数据操作层

    Spring Data JPA和Spring Data Elasticsearch共享相同的通用基础架构。与JPA存储库一样,基本原则是基于方法名称自动构造查询。

    public interface CityRepository extends ElasticsearchRepository<City,Long> {
    }
    

    ElasticsearchRepository源码

    @NoRepositoryBean
    public interface ElasticsearchRepository<T, ID extends Serializable> extends ElasticsearchCrudRepository<T, ID> {
        <S extends T> S index(S var1);
        Iterable<T> search(QueryBuilder var1);
        Page<T> search(QueryBuilder var1, Pageable var2);
        Page<T> search(SearchQuery var1);
        Page<T> searchSimilar(T var1, String[] var2, Pageable var3);
        void refresh();
        Class<T> getEntityClass();
    }
    

    为什么具有Crud操作呢

    注意看以下继承关系

    public interface ElasticsearchCrudRepository<T, ID extends Serializable> extends PagingAndSortingRepository<T, ID>
    public interface PagingAndSortingRepository<T, ID> extends CrudRepository<T, ID>
    

    不难发现最后有继承CrudRepository接口
    CrudRepository源码

    @NoRepositoryBean
    public interface CrudRepository<T, ID> extends Repository<T, ID> {
        <S extends T> S save(S var1);
        <S extends T> Iterable<S> saveAll(Iterable<S> var1);
        Optional<T> findById(ID var1);
        boolean existsById(ID var1);
        Iterable<T> findAll();
        Iterable<T> findAllById(Iterable<ID> var1);
        long count();
        void deleteById(ID var1);
        void delete(T var1);
        void deleteAll(Iterable<? extends T> var1);
        void deleteAll();
    }
    

    控制层

    实现简单的添加功能

    @RestController
    public class CityRestController {
        private final CityRepository cityRepository;
    
        @Autowired
        public CityRestController(CityRepository cityRepository) {
            this.cityRepository = cityRepository;
        }
    
        @PostMapping("/api/city")
        public City createCity(@RequestBody City city) {
            return cityRepository.save(city);
        }
    }
    
    yml配置文件
    spring:
      data:
        elasticsearch:
          cluster-nodes: localhost:9300
          cluster-name: my-application
    server:
      port: 8888
    
    注:记得修改目录config下的elasticsearch.yml配置文件

    1.把cluster.name:my-application注释打开
    2.network.host改为localhost,也就是network.host: localhost

    下面使用postman测试下

    image.png

    再插入一条数据

    {
        "id":2,
        "score":"5",
        "name":"广州",
        "description":"也是一线城市"
    }
    

    查看Elasticsearch的数据

    head插件下

    image.png

    kibana客户端下

    第一次进入kibana如果提示没索引就创建下,索引名就是indexName
    有Table和JSON两种查看方式

    image.png
    注:插入数据的主键如果相同,新数据将会覆盖旧数据

    推荐参考:

    接口文档:
    https://docs.spring.io/spring-data/elasticsearch/docs/3.1.3.RELEASE/reference/html/
    API文档:
    https://docs.spring.io/spring-data/elasticsearch/docs/3.1.3.RELEASE/api/

    相关文章

      网友评论

        本文标题:Elasticsearch与SpringBoot进行集成(未完)

        本文链接:https://www.haomeiwen.com/subject/pudulqtx.html