ElasticSearch系列之实操篇-SpringBoot中对Elasticsearch的增删改查操作

SpringBoot中对Elasticsearch的增删改查操作

  • 引包
  • 配置ES
  • 实体类
  • @Document中各个参数解释
      • 使用ElasticsearchTemplate完成增删改查操作
    • 查(分页查询,条件查询)
      • 条件查询
    • 排序
    • 分页
    • 增改
    • 删除

突然接到一个搜索的项目,需要新增一个版本,后台页面数据是存放在ElasticSearch中的,由于之前在实际项目当中从未用过ES,再加上只给了两天时间就需要完成页面和接口的开发,所以显得有些局促,不过好歹顺利完成,将学到的ES使用记录下来。

本文是通过spring-data-elasticsearch来操作ES的

引包

<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-elasticsearch</artifactId>
/dependency>

配置ES

spring:
  data:
    elasticsearch:
      cluster-name: elasticsearch #注意
      cluster-nodes: 127.0.0.1:9200 # 多个节点用逗号分开

注意:配置cluster-name的时候值一定要与下图红线框起来的一致。
在这里插入图片描述

实体类

想要操作ES中的索引是需要创建一个实体类
例如我所需要操作的是一个广告类:


import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;

/**
 * 广告索引
 *
 */
@Data

@Document(indexName = "adsInfos", type = "adsType", shards = 6, replicas = 2, refreshInterval = "0s")
public class Es_AdsInfo {

    @Id
    private Object id;
    @Field
    private Object adsName;  //广告图名称
    @Field
    private Object adsTypes; //广告图类型
    @Field
    private Object adsKeyWords;//匹配关键字
    @Field
    private Object adsStartTime;//推广开始时间
    @Field
    private Object adsEndTime;//推广结束时间
    @Field
    private Object adsPCImg;//PC端广告图地址
    @Field
    private Object adsMobileImg;//移动端广告图地址
    @Field
    private Object adsPCLink;//PC端跳转地址
    @Field
    private Object adsMobileLink;//移动端跳转地址
    @Field
    private Object addTime;//添加时间段
    @Field
    private Object insertDateTime;  //入库时间
    @Field
    private Object updateDateTime;  //更新时间
    @Field
    private Object field1;  //备用字段
    @Field
    private Object field2;  //备用字段
    @Field
    private Object field3;  //备用字段
    @Field
    private Object field4;  //备用字段
    @Field
    private Object field5;  //备用字段
}

在实体类中可以看到有一个@Document注解,里面有indexName,type,shards,replicas,refreshInterval

@Document中各个参数解释

事先声明:ES中的索引类似于普通关系型数据库(如:mysql,sqlserver)的数据库,而ES中的type则相当于数据库中的表。

  • indexName 索引名称 代表的是es中的具体某个索引
  • type 索引类型 代表的是索引中某个type
  • shards 分片数量 可以不要
  • replicas 备份数量 可以不要
  • refreshInterval 刷新间隔 可以不要

以上几个参数必须要有indexName 和 type 其他三个可以不写
比如可以这样

 @Document(indexName = "adsInfos", type = "adsType"")

使用ElasticsearchTemplate完成增删改查操作

使用ElasticsearchTemplate完全不需要有Dao层和service层,直接controller附带一个实体类就搞定一切。话不多说,上代码。

查(分页查询,条件查询)

/**
     * 数据查找
     *
     * @return
     */
    @RequestMapping(value = "getPageList", method = RequestMethod.GET)
    public Page<Es_KuaiSou_AdsInfo>  findPageList(@PageableDefault(size = 12) Pageable pageable, @RequestParam(name="title",required = false)String title) {
        SortBuilder sortBuilder = SortBuilders.fieldSort("insertDateTime").order(SortOrder.DESC);
        SearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(matchAllQuery()).withSort(sortBuilder).withPageable(pageable).build();
        Page<Es_KuaiSou_AdsInfo> perfect_indices = elasticsearchTemplate.queryForPage(searchQuery, Es_KuaiSou_AdsInfo.class);
        return  perfect_indices;
    }

完全没有看错,简简单单的三两行代码搞定查询。
但需要注意一下几点,如何使用条件查询?排序?分页查询?

条件查询

如果想要使用条件查询的话只需要在NativeSearchQueryBuilder后点一个withQuery对象出来withQuery(字段名,参数)
效果:
new NativeSearchQueryBuilder().withQuery(matchQuery("adsName","开屏广告"))
这就是对adsName字段进行筛选,查出adsName等于开屏广告的数据

排序

想要按某个字段排序的话就需要new一个SortBuilder对象

SortBuilder sortBuilder = SortBuilders.fieldSort("time").order(SortOrder.DESC);

创建完SortBuilder 对象以后再new NativeSearchQueryBuilder()后边点一个withSort()把sortBuilder 对象放括号里
效果:

SearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withSort(sortBuilder).build();

分页

因为ES默认只返回10条数据,想要每页多返回几条需要创建Pageable对象
比如我这里是在查询方法加了注解@PageableDefault(size = 12) Pageable pageable,改为ES默认返回12条数据。

效果:

SearchQuery searchQuery = new NativeSearchQueryBuilder().withPageable(pageable).build();

当所有查询条件都就位之后效果是这样的:

SortBuilder sortBuilder = SortBuilders.fieldSort("time").order(SortOrder.DESC);
SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchQuery("adsName","开屏广告")).withSort(sortBuilder).withPageable(pageable).build();

然后再将SearchQuery 对象交给elasticsearchTemplate.queryForPage()

最终效果:

 /**
     * 数据查找
     *
     * @return
     */
    @RequestMapping(value = "getPageList", method = RequestMethod.GET)
    public Page<Es_AdsInfo>  findPageList(@PageableDefault(size = 12) Pageable pageable, @RequestParam(name="adsName",required = false)String adsName) {
        SortBuilder sortBuilder = SortBuilders.fieldSort("time").order(SortOrder.DESC);
		SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchQuery("adsName",adsName).withSort(sortBuilder).withPageable(pageable).build();
        Page<Es_AdsInfo> perfect_indices = elasticsearchTemplate.queryForPage(searchQuery, Es_AdsInfo.class);
        return  perfect_indices;
    }

增改

这里增改在一个方法里实现了,当新增数据时生成的id在ES里查找不到就会新增一条数据,当修改的时候由于ES里已经存在一个一模一样id的数据,此时就是对这条数据进行了修改。

    /**
     * 数据添加/修改
     *
     * @return
     */
    @RequestMapping(value = "save", method = RequestMethod.POST)
    public void save(@RequestBody Es_AdsInfo es_AdsInfo) throws IOException {

        //修改数据
        String id = UUID.randomUUID().toString();
        if(null == es_AdsInfo.getId()){
            es_AdsInfo.setId(id);
        }
        List<IndexQuery> queries = new ArrayList<>();
        IndexQuery indexQuery = new IndexQuery();
        indexQuery.setId(es_AdsInfo.getId().toString());
        indexQuery.setObject(es_AdsInfo);
        indexQuery.setIndexName("adsInfos");
        indexQuery.setType("adsType");
        queries.add(indexQuery);
        elasticsearchTemplate.bulkIndex(queries);

    }

删除

删除的话把id传过来使用elasticsearchTemplate执行delete操作就可以了。
delete(“adsInfos”,“adsType”,id)
我们看到delete方法中有三个参数,分别为索引名称,索引类型,和要删除数据的id。

/**
     * 数据删除
     *
     * @return
     */
    @RequestMapping(value = "deleted", method = RequestMethod.DELETE)
    public void deleted(String id) {
        elasticsearchTemplate.delete("adsInfos","adsType",id);
    }

你可能感兴趣的:(SpringBoot操作ES,ElasticSearch,ES)