SpringBoot集成Elasticsearch(二) SpringDataElasticsearch基本的使用

SpringBoot集成Elasticsearch(二)

  • 前言
    • 实体类的编写
    • Dao的编写
    • setting和mapping文件的配置
      • setting的配置
      • mapping的配置
    • Es的聚合查询
      • ElasticSearchRepository的基本使用
    • 结语

前言

Es的基本安装与配置参考我这篇文章 SpringBoot集成Elasticsearch(一)
本文使用kotlin来解释说明,其他语言可对照修改代码

实体类的编写

代码实现:

@Document(indexName = "brand_es", type = "brand_es")
open class EsBrand {

    @org.springframework.data.annotation.Id
    @Field(type = FieldType.Keyword)
    var brandID: String? = null

    @Field(type = FieldType.Text,analyzer = "pinyin_analyzer",searchAnalyzer = "pinyin_analyzer",fielddata = true)
    var brandCname: String? = null

    @Field(type = FieldType.Text)
    var brandName: String? = null
    
    @Field(type = FieldType.Keyword)
    var brandLogo: String? = null
}

注解说明:
@Document注解标明实体是Elasticsearch的Document,放在类上

public @interface Document {

	String indexName();//索引库的名称,只能小写,不要用特殊字符,不能超过255字节

    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;
    
    VersionType versionType() default VersionType.EXTERNAL;
}

@Field注解标明了字段的配置

public @interface Field {

	@AliasFor("name")
	String value() default ""; //默认值

	@AliasFor("value")
	String name() default "";//存在es的属性名,默认为定义的实体名

	FieldType type() default FieldType.Auto;//自动检测属性的类型,可以根据实际情况自己设置
	注:整体单词使用keyword,文本使用text
	
	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 {};
}

Dao的编写

open interface BrandRepository : ElasticsearchRepository<EsBrand, String> {
    fun findByBrandCname(brandCname: String): List<EsBrand>
    fun deleteByBrandID(brandId: String)
    fun findByBrandID(brandId: String): Optional<EsBrand>
}

定义一个接口继承ElasticsearchRepository,第一个参数为实体类,第二个参数为主键属性

SpringBoot集成Elasticsearch(二) SpringDataElasticsearch基本的使用_第1张图片

setting和mapping文件的配置

setting的配置

在resources下创建elasticsearch_setting.json 文件

{
  "index": {
    "analysis": {
      "analyzer": {
        "pinyin_analyzer": {
          "type": "custom",
          "tokenizer": "ik_smart",//使用的分词器
          "filter": ["my_pinyin", "word_delimiter"]//分词器过滤
        }
      },
      "filter": {
        "my_pinyin": {
          "type": "pinyin",//你的插件的文件夹的名字
          "keep_first_letter": true,//true:支持首字母
          "keep_separate_first_letter": true,//支持首字母分隔
          "keep_full_pinyin": true,//true:支持全拼
          "keep_original": true,
          "limit_first_letter_length": 16, //设置最大长度
          "lowercase": true, //小写非中文字母
          "remove_duplicated_term": true //重复的项将被删除
        }
      }
    }
  }
}

然后在实体类添加注解

@Setting(settingPath = "elasticsearch_setting.json")//设置setting
@Document(indexName = "brand_es", type = "brand_es")
open class EsBrand

mapping的配置

在resources下创建elasticsearch_mapping.json 文件
注意:这里可以不需要mapping文件,定义mapping文件后实体类上字段的注解会失效

{
  "properties": {
    "uname": {
      "type": "text",
      "analyzer": "pinyin_analyzer",
      "search_analyzer": "pinyin_analyzer"
    },
    "age": {
      "type": "integer"
    }
  }
}
//引用mapping
@Mapping(mappingPath = "elasticsearch_mapping.json")//设置mapping

Es的聚合查询

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();
}

实际使用中,是通过构建NativeSearchQuery来完成一些复杂的查询的。
说明参考:ElasticSearchRepository的基本使用

QueryBuilder 的几个方法 QueryBuilder 的使用

//按自己设置的分词器搜索
QueryBuilders.matchQuery("brandCname",keyword)
//精确查询 完全匹配
QueryBuilders.termQuery("groupId",request.groupId)
//模糊匹配,以*为匹配符
QueryBuilders.wildcardQuery("brandName", "*$keyword*")
//组合查询,前面必须是QueryBuilders.boolQuery(),should代表or,must代表and
QueryBuilders.boolQuery().should(QueryBuilders.matchQuery("brandCname",keyword))
.must(QueryBuilders.wildcardQuery("brandName", "*$keyword*"))
//QueryBuilders是可以单独使用的
val esBrands = repository.search(query)

有时候需要自己排序,这时就要用到SortBuilder

SortBuilders.fieldSort("字段属性名").order(SortOrder.ASC);//字段排序

注意:要排序的字段必须添加 fielddata = true 的设置,否则会报错

分页查询

//通过PageRequest构建分页
val page = PageRequest.of(0, 2) //第一个参数是页码,第二个参数为每页返回条数,es的分页是从0开始的
val esBrands = repository.search(query,page)

有的人可能说了,我全都要怎么办,那就要用到下面的方法

NativeSearchQueryBuilder的构建

//聚合查询NativeSearchQueryBuilder的使用
 var fsb = SortBuilders.fieldSort("brandCname").order(SortOrder.ASC);
        var bqb = QueryBuilders.boolQuery().should(QueryBuilders.matchQuery("brandCname",keyword))
        .should(QueryBuilders.wildcardQuery("brandName", "*$keyword*"))
        var query = NativeSearchQueryBuilder()
                .withQuery(bqb)
                .withSort(fsb)
                .withPageable(pageable)
                .build();
//完整示例
open class EsBrandService {
    @Autowired
    private lateinit var repository: BrandRepository
	 fun fetchPageBrandsByKeyWord(keyword :String,pageable :PageRequest): List<EsBrand> {
        var fsb = SortBuilders.fieldSort("brandCname").order(SortOrder.ASC);
        var bqb = QueryBuilders.boolQuery().should(QueryBuilders.matchQuery("brandCname",keyword)).should(QueryBuilders.wildcardQuery("brandName", "*$keyword*"))
        var query = NativeSearchQueryBuilder()
                .withQuery(bqb)
                .withSort(fsb)
                .withPageable(pageable)
                .build();
        val esBrands = repository.search(query)
        val brands = Lists.newArrayList(esBrands)
        return brands
    }
}

结语

至此,已经满足了es的基本使用,一般线上服务器都是linux系统,这里可能需要配置es服务开机自启,
可以参考这篇文章 Elasticsearch 在CentOs7 环境中开机启动
最后欢迎大家指出这篇文章的不足,共同进步!!!

你可能感兴趣的:(SpringBoot,Elasticsearch,spring,data,elasticsearch)