初探 Spring Data Elasticsearch
Spring Data Elasticsearch 介绍
Spring Data Elasticsearch 基于 spring data API 简化 Elasticsearch 操作,将原始操作 Elasticsearch 的客户端 API 进行封装 。Spring Data 为 Elasticsearch 项目提供集成搜索引擎。
Spring Data Elasticsearch POJO 的关键功能区域为中心的模型与 Elastichsearch 交互文档和轻松地编写一个存储索引库数据访问层。
官网:Spring Data Elasticsearch
1.引入依赖并配置地址
① 在 SpringBoot 项目中引入 Spring Data Elasticsearch 的依赖
1 2 3 4
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency>
|
② 在 application.yml 中配置 Elasticsearch 的地址
1 2 3
| spring: elasticsearch: uris: http://192.168.10.155:9200
|
2.创建实体类以及对应的文档 Document 关系
① 创建实体类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
|
@Data @NoArgsConstructor @AllArgsConstructor @Document(indexName = "langbei") @Setting(shards = 1,replicas = 1) public class UserVo {
private static final long serialVersionUID = 1L;
@Id private long id;
@Field(name = "username") private String username;
@Field(name = "userAccount",type = FieldType.Text,searchAnalyzer="ik_max_word",analyzer="ik_max_word") private String userAccount;
@Field(name = "avatarUrl") private String avatarUrl;
@Field(name = "gender") private Integer gender;
@Field(name = "tags") private String tags;
@Field(name = "phone") private String phone;
@Field(name = "contactInfo") private String contactInfo;
@Field(name = "profile") private String profile;
@Field(name = "userStatus") private Integer userStatus;
@Field(name = "createTime") private Date createTime;
@Field(name = "updateTime") private Date updateTime;
@Field(name = "isDelete") private Integer isDelete;
@Field(name = "userRole") private Integer userRole;
@Field(name = "planetCode") private String planetCode;
}
|
注解介绍
@Document(indexName = “”) :
- 指定索引库的名字,网上大多会在此注解中配置分片数、副本数,但是观察源码会发现这两个属性已经被废弃
@Setting(shards = 1,replicas = 1) :
@Id,@Field(name = “”) :
- @Id 用于声明 mapper 的_id,必须声明
- @Field(..) 用于声明该字段的各个属性,比如字段名,字段类型,使用什么分词器,格式等
3.创建文档的管理 ElasticSearchRepository 接口
① 创建 UserVoRepository
- 继承 ElasticsearchRepository<**映射实体类**,**主键数据类型**>,里面有一些自带的方法
- 新增、更新数据:使用 repository 的 save()方法实现
- 删除数据:deleteById()、deleteAll()
- 查询:findById()、findAll()
- 自定义查询方法
- 方法名满足指定格式,就可以自定义查询方法
- findBy
{Titlte}
And{contnet}
(String title,String contnet);
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
@Repository public interface UserVoRepository extends ElasticsearchRepository<UserVo,Long> {
List<UserVo> findByUserAccount(String userAccount); }
|
4.创建 service
UserVoService.java 几个简单的方法
1 2 3 4 5 6 7 8 9 10 11 12 13
|
public interface UserVoService { List<UserVo> findByUserAccount(String userAccount);
void save(UserVo docBean);
void saveAll(List<UserVo> list);
Iterator<UserVo> findAll(); }
|
UserVoServiceImpl.java 实现类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
|
@Service public class UserVoServiceImpl implements UserVoService {
@Resource private UserVoRepository elasticRepository;
@Override public List<UserVo> findByUserAccount(String userAccount) { return elasticRepository.findByUserAccount(userAccount); }
@Override public void save(UserVo docBean) { elasticRepository.save(docBean); }
@Override public void saveAll(List<UserVo> list) { elasticRepository.saveAll(list); }
@Override public Iterator<UserVo> findAll() { return elasticRepository.findAll().iterator(); } }
|
5.简单测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
|
@SpringBootTest class UserVoServiceTest { @Resource UserVoService userVoService; @Resource UserService userService;
@Test void saveAll() { List<UserVo> list = userService.list().stream().map(user -> { UserVo userVo = new UserVo(); BeanUtils.copyProperties(user, userVo); return userVo; }).collect(Collectors.toList()); userVoService.saveAll(list); }
@Test void findAll() { Iterator<UserVo> all = userVoService.findAll(); while(all.hasNext()){ UserVo next = all.next(); System.out.println(next); } }
@Test void findByUserAccount() { List<UserVo> userVos = userVoService.findByUserAccount("4"); System.out.println(userVos); } }
|
6.复杂查询
参考:SpringDataElasticSearch 框架 - 掘金 (juejin.cn)
复杂查询需要使用 ElasticsearchRestTemplate对象
① 创建索引库以及 mapping 的方法
1 2 3 4 5 6 7
| template.indexOps(UserVo.class).create(); template.indexOps(IndexCoordinates.of("langbei")).create();
Document mapping = template.indexOps(UserVo.class).createMapping(); template.indexOps(UserVo.class).putMapping(mapping);
|
② 查询
- 使用 NativeSearchQuery 封装查询条件
- SearchHits searchHits = template.search(Query query, Class
<T>
clazz); 执行查询并得到查询结果
- 对结果处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| @Resource ElasticsearchRestTemplate template;
@Test void testElasticsearchRestTemplate(){ NativeSearchQuery query = new NativeSearchQueryBuilder() .withQuery(QueryBuilders.matchQuery("userAccount","4")) .withHighlightBuilder(new HighlightBuilder().field("userAccount").preTags("<em>").postTags("</em>")) .build(); SearchHits<UserVo> searchHits = template.search(query, UserVo.class); long totalHits = searchHits.getTotalHits(); System.out.println("totalHits = " + totalHits); List<SearchHit<UserVo>> searchHits1 = searchHits.getSearchHits(); searchHits1.forEach( e->{ UserVo content = e.getContent(); System.out.println("content = " + content); Map<String, List<String>> highlightFields = e.getHighlightFields(); List<String> highlightUserAccount = highlightFields.get("userAccount"); System.out.println(highlightUserAccount); }); }
|