赞
踩
平凡也就两个字: 懒和惰;
成功也就两个字: 苦和勤;
优秀也就两个字: 你和我。
跟着我从0学习JAVA、spring全家桶和linux运维等知识,带你从懵懂少年走向人生巅峰,迎娶白富美!
关注微信公众号【 IT特靠谱 】,每天都会分享技术心得~
创建的项目名称为:elasticsearch-demo
选择需要依赖的基础jar包。
创建成功后,项目结构如下图所示:
- <!--添加springboot-elasticsearch依赖-->
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
- </dependency>
由于之前的文章中,我们安装的是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就达到目的了!
将springboot版本调整为:2.3.0.RELEASE
自动下载完依赖后,查看依赖的es相关包版本:
到此,项目组依赖的es相关包版本与es服务版本相同了!都为:7.6.2版本
- #指定es服务访问url
- spring:
- elasticsearch:
- rest:
- uris: http://localhost:9200
创建实体类:User.java
- package com.test.elasticsearchdemo.entity;
-
- import java.io.Serializable;
- import java.util.Date;
- import java.util.List;
- import lombok.AllArgsConstructor;
- import lombok.Builder;
- import lombok.Data;
- import lombok.NoArgsConstructor;
- import org.springframework.data.annotation.Id;
- import org.springframework.data.annotation.Transient;
- import org.springframework.data.elasticsearch.annotations.Document;
- import org.springframework.data.elasticsearch.annotations.Field;
- import org.springframework.data.elasticsearch.annotations.FieldType;
-
- /**
- * 用户实体类
- */
- @Data
- @Builder
- @AllArgsConstructor
- @NoArgsConstructor
- @Document(indexName = "pms", type = "_doc") //es注解1。指定es索引名和类型。es8版本中会废弃掉type类型(实际上默认的type为"_doc")。
- public class User implements Serializable {
-
- /**
- * 数据id Id注解:指明pms索引_doc类型中的文档的id为数据的id。如果insert到es中的数据的id值为空,那么es会自动生成一个唯一的uuid作为文档id
- */
- @Id
- private Long id;
-
- /**
- * 用户名 Text:其取代了string,当一个字段是要被全文搜索的,比如Email内容、产品描述,应该使用text类型。 设置text类型以后,字段内容会被分词,在生成倒排索引以前,字符串会被分词器分成一个个词项。text类型的字段不用于排序,很少用于聚合(termsAggregation除外)。
- * ik_max_word:指示了该字段使用到的分词算法,为:最细粒度分词
- */
- @Field(analyzer = "ik_max_word", type = FieldType.Text)
- private String name;
-
- /**
- * 用户密码 注意:password字段添加@Transient注解,也就意味着该字段不会被写入es中!
- */
- @Transient
- private String password;
-
- /**
- * 用户手机号 Keyword:关键词。该类型字段只能通过"精确查找"方式索引到,不会对该字段分词后与查询条件匹配
- */
- @Field(type = FieldType.Keyword)
- private String mobile;
-
- /**
- * 用户年龄 Integer:整数类型
- */
- @Field(type = FieldType.Integer)
- private Integer age;
-
- /**
- * 用户生日 Date:日期类型
- */
- @Field(type = FieldType.Date)
- private Date birthday;
-
- /**
- * 删除标识 Boolean:bool类型
- */
- @Field(type = FieldType.Boolean)
- private Boolean deleteStatus;
-
- /**
- * 用户标签 Nested:嵌套类型
- */
- @Field(type = FieldType.Nested)
- private List<Label> labels;
-
- @Data
- @Builder
- @AllArgsConstructor
- @NoArgsConstructor
- public static class Label implements Serializable {
-
- /**
- * 标签id
- */
- @Field(type = FieldType.Long)
- private Long id;
-
- /**
- * 标签编码
- */
- @Field(type = FieldType.Keyword)
- private String labelCode;
-
- /**
- * 标签名称
- */
- @Field(type = FieldType.Keyword)
- private String labelName;
-
- /**
- * 标签名称 注意:该字段不会被写入es中!
- */
- @Transient
- private String labelDesc;
- }
- }
创建自定义es仓库接口:EsUserRepository.java,继承ElasticsearchRepository.java接口。
ElasticsearchRepository及其父接口封装了一些常用的CRUD方法。因此我们只需要继承该接口,就可以进行简单的增删改查操作了。当然如果希望实现更复杂的查询操作,就需要搭配RestHighLevelClient客户端来使用!
- package com.test.elasticsearchdemo.repository;
-
- import com.test.elasticsearchdemo.entity.User;
- import java.util.List;
- import org.springframework.data.domain.Page;
- import org.springframework.data.domain.Pageable;
- import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
-
- /**
- * ES用户repository
- */
- public interface EsUserRepository extends ElasticsearchRepository<User, Long> {
-
- /**
- * 根据名称查询
- */
- List<User> findByName(String name);
-
- /**
- * 分页搜索查询:分页查询名称或手机号相同的信息
- */
- Page<User> findByNameOrMobile(String name, String mobile, Pageable page);
- }
创建service接口类:UserService.java
- package com.test.elasticsearchdemo.service;
-
- import com.test.elasticsearchdemo.dto.request.PageByNameOrMobileRequest;
- import com.test.elasticsearchdemo.entity.User;
- import java.util.List;
- import org.springframework.data.domain.Page;
- import org.springframework.data.domain.Pageable;
-
- /**
- * 用户service接口类
- */
- public interface UserService {
-
- /**
- * 保存一条数据
- */
- void insert(User user);
-
- /**
- * 批量保存数据
- */
- void insertBatch(List<User> users);
-
- /**
- * 更新一条数据
- */
- void update(User user);
-
- /**
- * 删除一条数据
- * @param id 删除数据文档id(文档id与数据id相同)
- */
- void deleteById(Long id);
-
- /**
- * 根据名称查询
- */
- List<User> listByName(String name);
-
- /**
- * 根据id查询唯一数据
- */
- User findById(Long id);
-
- /**
- * 分页搜索查询:分页查询名称或手机号相同的信息
- */
- Page<User> findByNameOrMobile(PageByNameOrMobileRequest request);
-
- /**
- * 分页搜索查询:分页查询名称或手机号相同的信息,并按age升序排序
- */
- Page<User> pageByConditions(PageByNameOrMobileRequest request);
- }
创建service接口实现类:UserServiceImpl.java
- package com.test.elasticsearchdemo.service.impl;
-
- import com.test.elasticsearchdemo.dto.request.PageByNameOrMobileRequest;
- import com.test.elasticsearchdemo.entity.User;
- import com.test.elasticsearchdemo.repository.EsUserRepository;
- import com.test.elasticsearchdemo.service.UserService;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.Optional;
- import java.util.stream.Collectors;
- import org.elasticsearch.common.lucene.search.function.FunctionScoreQuery;
- import org.elasticsearch.index.query.BoolQueryBuilder;
- import org.elasticsearch.index.query.QueryBuilders;
- import org.elasticsearch.index.query.functionscore.FunctionScoreQueryBuilder;
- import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders;
- import org.elasticsearch.search.sort.SortBuilders;
- import org.elasticsearch.search.sort.SortOrder;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.data.domain.Page;
- import org.springframework.data.domain.PageImpl;
- import org.springframework.data.domain.PageRequest;
- import org.springframework.data.domain.Pageable;
- 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.stereotype.Service;
- import org.springframework.util.StringUtils;
-
- /**
- * 用户接口实现类
- */
- @Service
- public class UserServiceImpl implements UserService {
-
- /**
- * 一般CRUD查询用这个!spring-data风格
- */
- @Autowired
- private EsUserRepository esUserRepository;
-
- /**
- * es复杂操作用这个!底层用的是RestHighLevelClient客户端
- */
- @Autowired
- private ElasticsearchRestTemplate elasticsearchRestTemplate;
-
- /***********************EsUserRepository新增、更新和删除***********************/
- /**
- * 新增一条数据
- */
- @Override
- public void insert(User user) {
- esUserRepository.save(user);
- }
-
- /**
- * 批量保存数据
- */
- @Override
- public void insertBatch(List<User> users) {
- esUserRepository.saveAll(users);
- }
-
- /**
- * 更新一条数据 说明:如果es数据库中存在相同id的数据,那么就是更新数据!否则就是新增数据。
- */
- @Override
- public void update(User user) {
- esUserRepository.save(user);
- }
-
- /**
- * 删除一条数据
- *
- * @param id 删除数据文档id(文档id与数据id相同)
- */
- @Override
- public void deleteById(Long id) {
- esUserRepository.deleteById(id);
- }
-
- /***********************EsUserRepository普通查询***********************/
- /**
- * 根据名称查询
- */
- @Override
- public List<User> listByName(String name) {
- return esUserRepository.findByName(name);
- }
-
- /**
- * 根据id查询唯一数据
- */
- @Override
- public User findById(Long id) {
- Optional<User> optional = esUserRepository.findById(id);
- return optional.orElse(null);
- }
-
- /**
- * 分页搜索查询:分页查询名称或手机号相同的信息
- */
- @Override
- public Page<User> findByNameOrMobile(PageByNameOrMobileRequest request) {
- Pageable pageable = PageRequest.of(request.getPage()-1, request.getSize());
- return esUserRepository.findByNameOrMobile(request.getName(), request.getMobile(), pageable);
- }
-
- /***********************RestHighLevelClient高级查询***********************/
- @Override
- public Page<User> pageByConditions(PageByNameOrMobileRequest request) {
- //构建查询条件
- NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();
- //1.排序
- nativeSearchQueryBuilder.withSort(SortBuilders.fieldSort("age").order(SortOrder.ASC));
- //2.分页
- Pageable pageable = PageRequest.of(request.getPage() - 1, request.getSize());
- nativeSearchQueryBuilder.withPageable(pageable);
- //3.过滤
- BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
- boolQueryBuilder.must(QueryBuilders.termQuery("deleteStatus", false));
- nativeSearchQueryBuilder.withFilter(boolQueryBuilder);
- //4.搜索条件
- if (StringUtils.isEmpty(request.getMobile()) && StringUtils.isEmpty(request.getName())) {
- nativeSearchQueryBuilder.withQuery(QueryBuilders.matchAllQuery());
- } else {
- List<FunctionScoreQueryBuilder.FilterFunctionBuilder> filterFunctionBuilders = new ArrayList<>();
- if (!StringUtils.isEmpty(request.getMobile())) {
- filterFunctionBuilders.add(new FunctionScoreQueryBuilder.FilterFunctionBuilder(QueryBuilders.matchQuery("mobile", request.getMobile()),
- ScoreFunctionBuilders.weightFactorFunction(10)));
- }
- if (!StringUtils.isEmpty(request.getName())) {
- filterFunctionBuilders.add(new FunctionScoreQueryBuilder.FilterFunctionBuilder(QueryBuilders.matchQuery("name", request.getName()),
- ScoreFunctionBuilders.weightFactorFunction(7)));
- }
- FunctionScoreQueryBuilder.FilterFunctionBuilder[] builders = new FunctionScoreQueryBuilder.FilterFunctionBuilder[filterFunctionBuilders.size()];
- filterFunctionBuilders.toArray(builders);
- FunctionScoreQueryBuilder functionScoreQueryBuilder = QueryBuilders.functionScoreQuery(builders)
- .scoreMode(FunctionScoreQuery.ScoreMode.SUM)
- .setMinScore(3);
- nativeSearchQueryBuilder.withQuery(functionScoreQueryBuilder);
- }
- NativeSearchQuery query = nativeSearchQueryBuilder.build();
- SearchHits<User> searchHits = elasticsearchRestTemplate.search(query, User.class);
- if (searchHits.getTotalHits() <= 0) {
- return new PageImpl<>(null, pageable, 0);
- }
- List<User> userList = searchHits.stream().map(SearchHit::getContent).collect(Collectors.toList());
- return new PageImpl<>(userList, pageable, searchHits.getTotalHits());
- }
- }
创建控制器类:UserController.java
- package com.test.elasticsearchdemo.controller;
-
- import com.test.elasticsearchdemo.dto.request.PageByNameOrMobileRequest;
- import com.test.elasticsearchdemo.entity.User;
- import com.test.elasticsearchdemo.service.UserService;
- import java.util.List;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.data.domain.Page;
- import org.springframework.web.bind.annotation.GetMapping;
- import org.springframework.web.bind.annotation.PostMapping;
- import org.springframework.web.bind.annotation.RequestBody;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RestController;
-
- /**
- * 用户api接口控制器
- */
- @RestController
- @RequestMapping(value = "/user")
- public class UserController {
-
- @Autowired
- private UserService userService;
-
- /***********************EsUserRepository新增、更新和删除***********************/
- /**
- * 保存一条数据
- */
- @PostMapping("insert")
- public void insert(@RequestBody User user) {
- userService.insert(user);
- }
-
- /**
- * 批量保存数据
- */
- @PostMapping("insertBatch")
- public void insertBatch(@RequestBody List<User> users) {
- userService.insertBatch(users);
- }
-
- /**
- * 更新一条数据
- */
- @PostMapping("update")
- public void update(@RequestBody User user) {
- userService.update(user);
- }
-
- /**
- * 删除一条数据
- */
- @GetMapping("deleteById")
- public void deleteById(Long id) {
- userService.deleteById(id);
- }
-
- /***********************EsUserRepository普通查询***********************/
- /**
- * 根据名称查询
- */
- @GetMapping("listByName")
- public List<User> listByName(String name) {
- return userService.listByName(name);
- }
-
- /**
- * 根据id查询唯一数据
- */
- @GetMapping("findById")
- public User findById(Long id) {
- return userService.findById(id);
- }
-
- /**
- * 分页搜索查询:分页查询名称或手机号相同的信息
- */
- @PostMapping("findPageByNameOrMobile")
- public Page<User> findPageByNameOrMobile(@RequestBody PageByNameOrMobileRequest request) {
- return userService.findByNameOrMobile(request);
- }
-
- /***********************highLevelClient高级查询***********************/
- /**
- * 分页搜索查询:分页查询名称或手机号相同的信息,并按age升序排序
- */
- @PostMapping("pageByConditions")
- public Page<User> pageByConditions(@RequestBody PageByNameOrMobileRequest request) {
- return userService.pageByConditions(request);
- }
- }
到此,springboot整合Elasticsearch,并实现了基于repository和restHighLevel两种方式实现了数据的CRUD。
(1) 商务合作微信号:M9392W
(2) 购物商城: 扫码即可进入博主开发的小程序购物商城,享超大优惠购物,支持一下博主吧~
(3) 博主微信公众号:IT特靠谱,学习更多开发实战技巧!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。