当前位置:   article > 正文

springboot整合Elasticsearch实现增删改查_springboot elasticsearch增删改查

springboot elasticsearch增删改查

平凡也就两个字: 懒和惰;
成功也就两个字: 苦和勤;
优秀也就两个字: 你和我。
跟着我从0学习JAVA、spring全家桶和linux运维等知识,带你从懵懂少年走向人生巅峰,迎娶白富美!
关注微信公众号【 IT特靠谱 】,每天都会分享技术心得~

springboot整合Elasticsearch实现增删改查

1 创建springboot项目

      创建的项目名称为:elasticsearch-demo

      选择需要依赖的基础jar包。

      创建成功后,项目结构如下图所示:

2 添加springboot-elasticsearch依赖

  1. <!--添加springboot-elasticsearch依赖-->
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
  5. </dependency>

3 调整springboot版本

3.1 为什么要调整springboot版本?

      由于之前的文章中,我们安装的是7.6.2版本的elasticsearch。而创建的springboot项目是2.4.0版本的,其默认依赖的是7.9.3版本的elasticsearch相关包。

      如果项目用到的es相关包版本与安装的es服务版本不一致,在实际使用es进行CRUD的时候就会出现一些版本导致的未知问题。因此,我们需要调整项目依赖的es版本或者调整springboot版本!

      恰好!springboot的2.3.0.RELEASE版本,默认依赖的就是7.6.2版本的es相关依赖包。那么我们调整springboot版本为2.3.0.RELEASE就达到目的了!

3.2 调整springboot版本

      将springboot版本调整为:2.3.0.RELEASE

      自动下载完依赖后,查看依赖的es相关包版本:

      到此,项目组依赖的es相关包版本与es服务版本相同了!都为:7.6.2版本

4 编写代码

4.1 配置application.yml

  1. #指定es服务访问url
  2. spring:
  3. elasticsearch:
  4. rest:
  5. uris: http://localhost:9200

4.2 创建实体类

      创建实体类:User.java

  1. package com.test.elasticsearchdemo.entity;
  2. import java.io.Serializable;
  3. import java.util.Date;
  4. import java.util.List;
  5. import lombok.AllArgsConstructor;
  6. import lombok.Builder;
  7. import lombok.Data;
  8. import lombok.NoArgsConstructor;
  9. import org.springframework.data.annotation.Id;
  10. import org.springframework.data.annotation.Transient;
  11. import org.springframework.data.elasticsearch.annotations.Document;
  12. import org.springframework.data.elasticsearch.annotations.Field;
  13. import org.springframework.data.elasticsearch.annotations.FieldType;
  14. /**
  15. * 用户实体类
  16. */
  17. @Data
  18. @Builder
  19. @AllArgsConstructor
  20. @NoArgsConstructor
  21. @Document(indexName = "pms", type = "_doc") //es注解1。指定es索引名和类型。es8版本中会废弃掉type类型(实际上默认的type为"_doc")。
  22. public class User implements Serializable {
  23. /**
  24. * 数据id Id注解:指明pms索引_doc类型中的文档的id为数据的id。如果insert到es中的数据的id值为空,那么es会自动生成一个唯一的uuid作为文档id
  25. */
  26. @Id
  27. private Long id;
  28. /**
  29. * 用户名 Text:其取代了string,当一个字段是要被全文搜索的,比如Email内容、产品描述,应该使用text类型。 设置text类型以后,字段内容会被分词,在生成倒排索引以前,字符串会被分词器分成一个个词项。text类型的字段不用于排序,很少用于聚合(termsAggregation除外)。
  30. * ik_max_word:指示了该字段使用到的分词算法,为:最细粒度分词
  31. */
  32. @Field(analyzer = "ik_max_word", type = FieldType.Text)
  33. private String name;
  34. /**
  35. * 用户密码 注意:password字段添加@Transient注解,也就意味着该字段不会被写入es中!
  36. */
  37. @Transient
  38. private String password;
  39. /**
  40. * 用户手机号 Keyword:关键词。该类型字段只能通过"精确查找"方式索引到,不会对该字段分词后与查询条件匹配
  41. */
  42. @Field(type = FieldType.Keyword)
  43. private String mobile;
  44. /**
  45. * 用户年龄 Integer:整数类型
  46. */
  47. @Field(type = FieldType.Integer)
  48. private Integer age;
  49. /**
  50. * 用户生日 Date:日期类型
  51. */
  52. @Field(type = FieldType.Date)
  53. private Date birthday;
  54. /**
  55. * 删除标识 Boolean:bool类型
  56. */
  57. @Field(type = FieldType.Boolean)
  58. private Boolean deleteStatus;
  59. /**
  60. * 用户标签 Nested:嵌套类型
  61. */
  62. @Field(type = FieldType.Nested)
  63. private List<Label> labels;
  64. @Data
  65. @Builder
  66. @AllArgsConstructor
  67. @NoArgsConstructor
  68. public static class Label implements Serializable {
  69. /**
  70. * 标签id
  71. */
  72. @Field(type = FieldType.Long)
  73. private Long id;
  74. /**
  75. * 标签编码
  76. */
  77. @Field(type = FieldType.Keyword)
  78. private String labelCode;
  79. /**
  80. * 标签名称
  81. */
  82. @Field(type = FieldType.Keyword)
  83. private String labelName;
  84. /**
  85. * 标签名称 注意:该字段不会被写入es中!
  86. */
  87. @Transient
  88. private String labelDesc;
  89. }
  90. }

4.3 自定义ElasticsearchRepository

      创建自定义es仓库接口:EsUserRepository.java,继承ElasticsearchRepository.java接口。

      ElasticsearchRepository及其父接口封装了一些常用的CRUD方法。因此我们只需要继承该接口,就可以进行简单的增删改查操作了。当然如果希望实现更复杂的查询操作,就需要搭配RestHighLevelClient客户端来使用!

  1. package com.test.elasticsearchdemo.repository;
  2. import com.test.elasticsearchdemo.entity.User;
  3. import java.util.List;
  4. import org.springframework.data.domain.Page;
  5. import org.springframework.data.domain.Pageable;
  6. import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
  7. /**
  8. * ES用户repository
  9. */
  10. public interface EsUserRepository extends ElasticsearchRepository<User, Long> {
  11. /**
  12. * 根据名称查询
  13. */
  14. List<User> findByName(String name);
  15. /**
  16. * 分页搜索查询:分页查询名称或手机号相同的信息
  17. */
  18. Page<User> findByNameOrMobile(String name, String mobile, Pageable page);
  19. }

4.4 创建service接口类

      创建service接口类:UserService.java

  1. package com.test.elasticsearchdemo.service;
  2. import com.test.elasticsearchdemo.dto.request.PageByNameOrMobileRequest;
  3. import com.test.elasticsearchdemo.entity.User;
  4. import java.util.List;
  5. import org.springframework.data.domain.Page;
  6. import org.springframework.data.domain.Pageable;
  7. /**
  8. * 用户service接口类
  9. */
  10. public interface UserService {
  11. /**
  12. * 保存一条数据
  13. */
  14. void insert(User user);
  15. /**
  16. * 批量保存数据
  17. */
  18. void insertBatch(List<User> users);
  19. /**
  20. * 更新一条数据
  21. */
  22. void update(User user);
  23. /**
  24. * 删除一条数据
  25. * @param id 删除数据文档id(文档id与数据id相同)
  26. */
  27. void deleteById(Long id);
  28. /**
  29. * 根据名称查询
  30. */
  31. List<User> listByName(String name);
  32. /**
  33. * 根据id查询唯一数据
  34. */
  35. User findById(Long id);
  36. /**
  37. * 分页搜索查询:分页查询名称或手机号相同的信息
  38. */
  39. Page<User> findByNameOrMobile(PageByNameOrMobileRequest request);
  40. /**
  41. * 分页搜索查询:分页查询名称或手机号相同的信息,并按age升序排序
  42. */
  43. Page<User> pageByConditions(PageByNameOrMobileRequest request);
  44. }

4.5 创建service接口实现类

      创建service接口实现类:UserServiceImpl.java

  1. package com.test.elasticsearchdemo.service.impl;
  2. import com.test.elasticsearchdemo.dto.request.PageByNameOrMobileRequest;
  3. import com.test.elasticsearchdemo.entity.User;
  4. import com.test.elasticsearchdemo.repository.EsUserRepository;
  5. import com.test.elasticsearchdemo.service.UserService;
  6. import java.util.ArrayList;
  7. import java.util.List;
  8. import java.util.Optional;
  9. import java.util.stream.Collectors;
  10. import org.elasticsearch.common.lucene.search.function.FunctionScoreQuery;
  11. import org.elasticsearch.index.query.BoolQueryBuilder;
  12. import org.elasticsearch.index.query.QueryBuilders;
  13. import org.elasticsearch.index.query.functionscore.FunctionScoreQueryBuilder;
  14. import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders;
  15. import org.elasticsearch.search.sort.SortBuilders;
  16. import org.elasticsearch.search.sort.SortOrder;
  17. import org.springframework.beans.factory.annotation.Autowired;
  18. import org.springframework.data.domain.Page;
  19. import org.springframework.data.domain.PageImpl;
  20. import org.springframework.data.domain.PageRequest;
  21. import org.springframework.data.domain.Pageable;
  22. import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
  23. import org.springframework.data.elasticsearch.core.SearchHit;
  24. import org.springframework.data.elasticsearch.core.SearchHits;
  25. import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
  26. import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
  27. import org.springframework.stereotype.Service;
  28. import org.springframework.util.StringUtils;
  29. /**
  30. * 用户接口实现类
  31. */
  32. @Service
  33. public class UserServiceImpl implements UserService {
  34. /**
  35. * 一般CRUD查询用这个!spring-data风格
  36. */
  37. @Autowired
  38. private EsUserRepository esUserRepository;
  39. /**
  40. * es复杂操作用这个!底层用的是RestHighLevelClient客户端
  41. */
  42. @Autowired
  43. private ElasticsearchRestTemplate elasticsearchRestTemplate;
  44. /***********************EsUserRepository新增、更新和删除***********************/
  45. /**
  46. * 新增一条数据
  47. */
  48. @Override
  49. public void insert(User user) {
  50. esUserRepository.save(user);
  51. }
  52. /**
  53. * 批量保存数据
  54. */
  55. @Override
  56. public void insertBatch(List<User> users) {
  57. esUserRepository.saveAll(users);
  58. }
  59. /**
  60. * 更新一条数据 说明:如果es数据库中存在相同id的数据,那么就是更新数据!否则就是新增数据。
  61. */
  62. @Override
  63. public void update(User user) {
  64. esUserRepository.save(user);
  65. }
  66. /**
  67. * 删除一条数据
  68. *
  69. * @param id 删除数据文档id(文档id与数据id相同)
  70. */
  71. @Override
  72. public void deleteById(Long id) {
  73. esUserRepository.deleteById(id);
  74. }
  75. /***********************EsUserRepository普通查询***********************/
  76. /**
  77. * 根据名称查询
  78. */
  79. @Override
  80. public List<User> listByName(String name) {
  81. return esUserRepository.findByName(name);
  82. }
  83. /**
  84. * 根据id查询唯一数据
  85. */
  86. @Override
  87. public User findById(Long id) {
  88. Optional<User> optional = esUserRepository.findById(id);
  89. return optional.orElse(null);
  90. }
  91. /**
  92. * 分页搜索查询:分页查询名称或手机号相同的信息
  93. */
  94. @Override
  95. public Page<User> findByNameOrMobile(PageByNameOrMobileRequest request) {
  96. Pageable pageable = PageRequest.of(request.getPage()-1, request.getSize());
  97. return esUserRepository.findByNameOrMobile(request.getName(), request.getMobile(), pageable);
  98. }
  99. /***********************RestHighLevelClient高级查询***********************/
  100. @Override
  101. public Page<User> pageByConditions(PageByNameOrMobileRequest request) {
  102. //构建查询条件
  103. NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
  104. //1.排序
  105. nativeSearchQueryBuilder.withSort(SortBuilders.fieldSort("age").order(SortOrder.ASC));
  106. //2.分页
  107. Pageable pageable = PageRequest.of(request.getPage() - 1, request.getSize());
  108. nativeSearchQueryBuilder.withPageable(pageable);
  109. //3.过滤
  110. BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
  111. boolQueryBuilder.must(QueryBuilders.termQuery("deleteStatus", false));
  112. nativeSearchQueryBuilder.withFilter(boolQueryBuilder);
  113. //4.搜索条件
  114. if (StringUtils.isEmpty(request.getMobile()) && StringUtils.isEmpty(request.getName())) {
  115. nativeSearchQueryBuilder.withQuery(QueryBuilders.matchAllQuery());
  116. } else {
  117. List<FunctionScoreQueryBuilder.FilterFunctionBuilder> filterFunctionBuilders = new ArrayList<>();
  118. if (!StringUtils.isEmpty(request.getMobile())) {
  119. filterFunctionBuilders.add(new FunctionScoreQueryBuilder.FilterFunctionBuilder(QueryBuilders.matchQuery("mobile", request.getMobile()),
  120. ScoreFunctionBuilders.weightFactorFunction(10)));
  121. }
  122. if (!StringUtils.isEmpty(request.getName())) {
  123. filterFunctionBuilders.add(new FunctionScoreQueryBuilder.FilterFunctionBuilder(QueryBuilders.matchQuery("name", request.getName()),
  124. ScoreFunctionBuilders.weightFactorFunction(7)));
  125. }
  126. FunctionScoreQueryBuilder.FilterFunctionBuilder[] builders = new FunctionScoreQueryBuilder.FilterFunctionBuilder[filterFunctionBuilders.size()];
  127. filterFunctionBuilders.toArray(builders);
  128. FunctionScoreQueryBuilder functionScoreQueryBuilder = QueryBuilders.functionScoreQuery(builders)
  129. .scoreMode(FunctionScoreQuery.ScoreMode.SUM)
  130. .setMinScore(3);
  131. nativeSearchQueryBuilder.withQuery(functionScoreQueryBuilder);
  132. }
  133. NativeSearchQuery query = nativeSearchQueryBuilder.build();
  134. SearchHits<User> searchHits = elasticsearchRestTemplate.search(query, User.class);
  135. if (searchHits.getTotalHits() <= 0) {
  136. return new PageImpl<>(null, pageable, 0);
  137. }
  138. List<User> userList = searchHits.stream().map(SearchHit::getContent).collect(Collectors.toList());
  139. return new PageImpl<>(userList, pageable, searchHits.getTotalHits());
  140. }
  141. }

4.6 创建controller控制器类

      创建控制器类:UserController.java

  1. package com.test.elasticsearchdemo.controller;
  2. import com.test.elasticsearchdemo.dto.request.PageByNameOrMobileRequest;
  3. import com.test.elasticsearchdemo.entity.User;
  4. import com.test.elasticsearchdemo.service.UserService;
  5. import java.util.List;
  6. import org.springframework.beans.factory.annotation.Autowired;
  7. import org.springframework.data.domain.Page;
  8. import org.springframework.web.bind.annotation.GetMapping;
  9. import org.springframework.web.bind.annotation.PostMapping;
  10. import org.springframework.web.bind.annotation.RequestBody;
  11. import org.springframework.web.bind.annotation.RequestMapping;
  12. import org.springframework.web.bind.annotation.RestController;
  13. /**
  14. * 用户api接口控制器
  15. */
  16. @RestController
  17. @RequestMapping(value = "/user")
  18. public class UserController {
  19. @Autowired
  20. private UserService userService;
  21. /***********************EsUserRepository新增、更新和删除***********************/
  22. /**
  23. * 保存一条数据
  24. */
  25. @PostMapping("insert")
  26. public void insert(@RequestBody User user) {
  27. userService.insert(user);
  28. }
  29. /**
  30. * 批量保存数据
  31. */
  32. @PostMapping("insertBatch")
  33. public void insertBatch(@RequestBody List<User> users) {
  34. userService.insertBatch(users);
  35. }
  36. /**
  37. * 更新一条数据
  38. */
  39. @PostMapping("update")
  40. public void update(@RequestBody User user) {
  41. userService.update(user);
  42. }
  43. /**
  44. * 删除一条数据
  45. */
  46. @GetMapping("deleteById")
  47. public void deleteById(Long id) {
  48. userService.deleteById(id);
  49. }
  50. /***********************EsUserRepository普通查询***********************/
  51. /**
  52. * 根据名称查询
  53. */
  54. @GetMapping("listByName")
  55. public List<User> listByName(String name) {
  56. return userService.listByName(name);
  57. }
  58. /**
  59. * 根据id查询唯一数据
  60. */
  61. @GetMapping("findById")
  62. public User findById(Long id) {
  63. return userService.findById(id);
  64. }
  65. /**
  66. * 分页搜索查询:分页查询名称或手机号相同的信息
  67. */
  68. @PostMapping("findPageByNameOrMobile")
  69. public Page<User> findPageByNameOrMobile(@RequestBody PageByNameOrMobileRequest request) {
  70. return userService.findByNameOrMobile(request);
  71. }
  72. /***********************highLevelClient高级查询***********************/
  73. /**
  74. * 分页搜索查询:分页查询名称或手机号相同的信息,并按age升序排序
  75. */
  76. @PostMapping("pageByConditions")
  77. public Page<User> pageByConditions(@RequestBody PageByNameOrMobileRequest request) {
  78. return userService.pageByConditions(request);
  79. }
  80. }

      到此,springboot整合Elasticsearch,并实现了基于repository和restHighLevel两种方式实现了数据的CRUD。

    (1) 商务合作微信号:M9392W

    (2) 购物商城: 扫码即可进入博主开发的小程序购物商城,享超大优惠购物,支持一下博主吧~

    (3) 博主微信公众号IT特靠谱,学习更多开发实战技巧!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/68746
推荐阅读
相关标签
  

闽ICP备14008679号