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 {@Idprivate Object id;@Fieldprivate Object adsName; //广告图名称@Fieldprivate Object adsTypes; //广告图类型@Fieldprivate Object adsKeyWords;//匹配关键字@Fieldprivate Object adsStartTime;//推广开始时间@Fieldprivate Object adsEndTime;//推广结束时间@Fieldprivate Object adsPCImg;//PC端广告图地址@Fieldprivate Object adsMobileImg;//移动端广告图地址@Fieldprivate Object adsPCLink;//PC端跳转地址@Fieldprivate Object adsMobileLink;//移动端跳转地址@Fieldprivate Object addTime;//添加时间段@Fieldprivate Object insertDateTime; //入库时间@Fieldprivate Object updateDateTime; //更新时间@Fieldprivate Object field1; //备用字段@Fieldprivate Object field2; //备用字段@Fieldprivate Object field3; //备用字段@Fieldprivate Object field4; //备用字段@Fieldprivate 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);}