SpringBoot(7) ------>整合Elasticsearch
1、向pom文件添加依赖
<!--SpringBoot 默认使用spring-boot-starter-data-elasticsearch--> <!-- elasticsearch --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency>
2、application.yml添加配置
spring: data: elasticsearch: repositories: enabled: true cluster-nodes: 127.0.0.1:9300 cluster-name: es client: reactive: socket-timeout: 5000
3、model层
1)Role
@Data @EqualsAndHashCode(callSuper = false) public class Role implements Serializable { private static final long serialVersionUID = 1L; /** * 主键 */ @TableId(value = "id", type = IdType.AUTO) private Integer id; /** * 角色名 */ private String roleName; /** * 角色编号 */ private String roleCode; /** * 角色介绍 */ private String introduce; }
2)EsRole
** * @author liangd * date 2020-12-18 09:38 * code */ @Data @NoArgsConstructor @AllArgsConstructor @EqualsAndHashCode(callSuper = false) @Document(indexName = "role",shards = 2,replicas = 1) public class EsRole implements Serializable { /** * Shard=1:存储到第一个切片 * replicas =0: 不备份 * FieldType.Keyword:存储数据时候,不会分词建立索引 * FieldType.Text:存储数据时候,会自动分词,并生成索引 * *ik_max_word与ik_smart区别? * ik_max_word * 会将文本做最细粒度的拆分,比如会将“中华人民共和国人民大会堂”拆分为“中华人民共和国、中华人民、中华、华人、 * 人民共和国、人民、共和国、大会堂、大会、会堂等词语。 * ik_smart * 会做最粗粒度的拆分,比如会将“中华人民共和国人民大会堂”拆分为中华人民共和国、人民大会堂。 * */ private static final long serialVersionUID = 1L; /** * 主键 */ @TableId(value = "id", type = IdType.AUTO) private Integer id; /** * 角色名 */ @Field(analyzer = "ik_max_word",type = FieldType.Text) private String roleName; /** * 角色编号 */ @Field(type = FieldType.Keyword) private String roleCode; /** * 角色介绍 */ private String introduce; }
4、接口层
EsService
/** * @author liangd * date 2020-12-18 09:49 * code */ public interface EsRoleService { /** * 从数据库中导入所有角色到ES */ int importAll(); /** * 根据id删除 */ void delete(Integer id); /** * 根据关键字搜索名称或者副标题 */ Page<EsRole> search(String keyword, Integer pageNum, Integer pageSize); // void deleteById(Long id); // // Page esRoleService(String keyword, Integer pageNum, Integer pageSize); /** * 高亮搜索 * @param keyword * @return */ SearchHits searchHit(String keyword); /** * 高亮搜索 * @param roleName * @return CommonResult */ CommonResult transferSearchHit(String roleName); }
5、接口实现层
新建EsServiceImpl
package com.donleo.elastic.service.impl; import com.donleo.elastic.common.CommonResult; import com.donleo.elastic.mapper.RoleMapper; import com.donleo.elastic.model.Role; import com.donleo.elastic.repository.EsRoleRepository; import com.donleo.elastic.service.EsRoleService; import com.donleo.elastic.vo.EsRole; import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate; import org.springframework.data.elasticsearch.core.SearchHit; import org.springframework.data.elasticsearch.core.SearchHits; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder; import org.springframework.data.elasticsearch.core.query.Query; import org.springframework.stereotype.Service; import java.lang.reflect.Field; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import static org.elasticsearch.index.query.QueryBuilders.matchQuery; /** * @author liangd * date 2020-12-18 09:53 * code 数据与es交互 */ @Service public class EsRoleServiceImpl implements EsRoleService { @Autowired private EsRoleRepository esRoleRepository; @Autowired private RoleMapper roleMapper; @Autowired private ElasticsearchRestTemplate restTemplate; @Override public int importAll() { List<Role> roleList = roleMapper.selectList(null); //将roleList里面的数据浅拷贝到es中 List<EsRole> collect = roleList.stream().map(role -> { EsRole esRole = new EsRole(); BeanUtils.copyProperties(role, esRole); return esRole; }).collect(Collectors.toList()); //方式一 // collect.forEach(esRoleRepository::save); //方式二 esRoleRepository.saveAll(collect); return roleList.size(); } @Override public void delete(Integer id) { EsRole esRole = new EsRole(); esRole.setId(id); esRoleRepository.delete(esRole); } @Override public Page<EsRole> search(String keyword, Integer pageNum, Integer pageSize) { NativeSearchQuery roleName = new NativeSearchQueryBuilder() .withQuery(matchQuery("roleName", keyword)).build(); return esRoleRepository.search(roleName); } @Override public SearchHits searchHit(String keyword) { Query query = new NativeSearchQueryBuilder() .withQuery(matchQuery("roleName", keyword)) .withHighlightFields( new HighlightBuilder.Field("roleName") .preTags("<font style='color:red'>").postTags("</font>") ).build(); return restTemplate.search(query, EsRole.class); } /** * * @param roleName 高亮显示的字段 * @return */ @Override public CommonResult transferSearchHit(String roleName) { Query query = new NativeSearchQueryBuilder() .withQuery(matchQuery("roleName", roleName)) .withHighlightFields( new HighlightBuilder.Field("roleName") .preTags("<font style='color:red'>").postTags("</font>") ).build(); SearchHits<EsRole> search = restTemplate.search(query, EsRole.class); List<EsRole> collect = tansferSearchHitToEsRole(search); return CommonResult.success(collect); } /** * 1、获取searchHits * 2、获取content * 3、获取highlightFields * 4、利用反射将highlightFields的字段值赋值给context的字段值 * 5、用collect将map对象收集起来转换为集合 * @param search * @return */ private List<EsRole> tansferSearchHitToEsRole(SearchHits<EsRole> search){ List<SearchHit<EsRole>> searchHits = search.getSearchHits(); List<EsRole> collect = searchHits.stream().map(searchHit -> { EsRole content = searchHit.getContent(); Map<String, List<String>> highlightFields = searchHit.getHighlightFields(); highlightFields.forEach((k, v) -> { StringBuilder temp = new StringBuilder(); for (String value : v) { temp.append(value); } String s = temp.toString(); try { Field keyField = EsRole.class.getDeclaredField(k); keyField.setAccessible(true); keyField.set(content, s); } catch (Exception e) { e.printStackTrace(); } }); return content; }).collect(Collectors.toList()); return collect; } }
6、持久层
package com.donleo.elastic.repository; import com.donleo.elastic.vo.EsRole; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; /** * @author liangd * date 2020-12-18 09:46 * code */ public interface EsRoleRepository extends ElasticsearchRepository<EsRole,Integer> { }
7、控制层
package com.donleo.elastic.controller; import com.donleo.elastic.common.CommonResult; import com.donleo.elastic.model.Role; import com.donleo.elastic.service.EsRoleService; import com.donleo.elastic.service.RoleService; import com.donleo.elastic.vo.EsRole; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.elasticsearch.core.SearchHits; import org.springframework.web.bind.annotation.*; import java.util.List; /** * <p> * 前端控制器 * </p> * * @author liangd * @since 2020-12-18 */ @RestController @RequestMapping("/role") public class RoleController { @Autowired private RoleService roleService; @Autowired private EsRoleService esRoleService; @GetMapping("/findAll") public CommonResult findAll(){ List<Role> list = roleService.list(); return CommonResult.success(list); } /** * 导入es * @return */ @GetMapping("/importEsAll") public CommonResult importEsAll(){ int result = esRoleService.importAll(); return CommonResult.success(result); } /** * 高亮搜索 * @return searchHits */ @GetMapping("/searchHit") public CommonResult searchHit(String roleName){ SearchHits searchHits = esRoleService.searchHit(roleName); return CommonResult.success(searchHits); } /** * 高亮搜索 * 只返回esRolemodel数据 * @return CommonResult */ @GetMapping("/transferSearchHit") public CommonResult transferSearchHit(String roleName){ return esRoleService.transferSearchHit(roleName); } /** * 分页搜索 //待完善 * @return Page<EsRole> */ @GetMapping("/searchPage") public CommonResult searchPage(String roleName,Integer pageNum,Integer pageSize){ Page<EsRole> search = esRoleService.search(roleName, pageNum, pageSize); return CommonResult.success(search); } /** * 删除 * @param id * @return */ @DeleteMapping("/deleteEs") public CommonResult deleteEs(@RequestParam Integer id){ esRoleService.delete(id); return CommonResult.success(1); } }