04_SpringBoot整合ElasticSearch

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: 04_SpringBoot整合ElasticSearch

1. 环境配置

pom.xml
<dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>7.8.0</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
            <version>2.4.0</version>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch</groupId>
            <artifactId>elasticsearch</artifactId>
            <version>7.8.0</version>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>transport</artifactId>
            <version>7.8.0</version>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-client</artifactId>
            <version>7.8.0</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.70</version>
        </dependency>
application.yaml
# 项目名
server:
  servlet:
    context-path: /es_demo
spring:
  elasticsearch:
    uris: localhost:9200
    connection-timeout: 5s
    socket-timeout: 30s

2. ElasticSearch配置类

@Configuration
public class ElasticsearchConfig {
    @Bean
    public RestHighLevelClient restHighLevelClient(){
        RestHighLevelClient client=new RestHighLevelClient(
                RestClient.builder(
                        new HttpHost("192.168.4.221",9200,"http")
                )
        );
        return client;
    }
}

3. 文档Document 对象

@Document(indexName="myuser")
public class User {
    @Id
    private Integer id;
    @Field(type = FieldType.Auto)//自动检测类型
    private Integer age;
    @Field(type = FieldType.Keyword)//手动设置为keyword  但同时也就不能分词
    private String name;
    @Field(type = FieldType.Text,analyzer = "ik_smart",searchAnalyzer = "ik_max_word")//设置为text  可以分词
    private String info;
    public User(){}
    public User(Integer id, Integer age, String name, String info) {
        this.id = id;
        this.age = age;
        this.name = name;
        this.info = info;
    }
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getInfo() {
        return info;
    }
    public void setInfo(String info) {
        this.info = info;
    }
    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", age=" + age +
                ", name='" + name + '\'' +
                ", info='" + info + '\'' +
                '}';
    }
}

3. service

@Service
  @Repository
// crud: create retrive update delete
public interface EsUserService extends ElasticsearchRepository<User,Integer> {
    List<User> findByName(String userName);
    List<User> findByInfo(String userInfo);
}
public interface EsUserService2 {
   public Map<String,Object> getUserList(String name, String info, Integer pageNum);
}
@Service
public class EsUserServiceImpl implements EsUserService2 {
    @Autowired
    private ElasticsearchRestTemplate restTemplate;
    @Override
    public Map<String,Object>  getUserList(String name, String info, Integer pageNum) {
       if(pageNum == null)
           pageNum = 1;
        Pageable pageable= PageRequest.of(pageNum-1,3);
        BoolQueryBuilder boolQueryBuilder=new BoolQueryBuilder();
        if(name!=null){
            QueryBuilder queryBuilder= QueryBuilders.queryStringQuery(name);
            boolQueryBuilder.must(queryBuilder);
        }else{
            if(info!=null) {
                boolQueryBuilder.must(new MatchQueryBuilder("info", info));
            }
        }
        SortBuilder sortBuilder= SortBuilders.scoreSort();
        FieldSortBuilder age = SortBuilders.fieldSort("age");
        sortBuilder.order(SortOrder.DESC);
        //构建高亮查询
       /* NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(boolQueryBuilder)
                .withHighlightFields(
                        new HighlightBuilder.Field("info"),
                        new HighlightBuilder.Field("name"))
                .withHighlightBuilder(new HighlightBuilder()
                        .preTags("<span style='color:red'>")
                        .postTags("</span>"))
                .build();
        */
        NativeSearchQueryBuilder builder=new NativeSearchQueryBuilder();
        NativeSearchQuery query=builder
                .withQuery(boolQueryBuilder)
                .withPageable(pageable)
                .withSort(sortBuilder)
                .withHighlightFields(
                        new HighlightBuilder.Field("info"),
                        new HighlightBuilder.Field("name"))
                .withHighlightBuilder(new HighlightBuilder()
                        .preTags("<span style='color:red'>")
                        .postTags("</span>"))
                .build();
        SearchHits<User> search = restTemplate.search(query, User.class);
        List<User> userList=new ArrayList<>();
        for(SearchHit<User> searchHit:search){
            //高亮内容
            Map<String ,List<String>> highlightFields = searchHit.getHighlightFields();
            //将高亮的内容填充到content中
            String highLightName = highlightFields.get("name") ==null ?searchHit.getContent().getName() :highlightFields.get("name").get(0);
            String highLightInfo = highlightFields.get("info") ==null ?searchHit.getContent().getName() :highlightFields.get("info").get(0);
            searchHit.getContent().setName(highLightName );
            searchHit.getContent().setInfo(highLightInfo);
            //放到实体类中
            userList.add(searchHit.getContent());
           /* User user1=user.getContent();
            userList.add(user1);
            System.out.println(user1);*/
        }
        SearchPage<User> searchPage= SearchHitSupport.searchPageFor(search,query.getPageable());
        //总记录数
        long totalElements=searchPage.getTotalElements();
        //总页数
        int totalPages=searchPage.getTotalPages();
        //当前页数
        int currentPage=searchPage.getPageable().getPageNumber();
        System.out.println(currentPage);
        Map<String,Object> map=new HashMap<>();
        map.put("totalElements",totalElements);
        map.put("totalPages",totalPages);
        map.put("currentPage",currentPage);
        map.put("user",userList);
        return map;
    }
}

4. controller

@RestController
public class EsUserController {
    @Autowired
    private ElasticsearchRestTemplate restTemplate;
    @Autowired
    private EsUserService userService;
    @Autowired
    private EsUserService2 userService2;
    private String[] names = {"诸葛亮","曹操","李白","韩信","赵云","小乔","狄仁杰","李四","诸小明","王五"};
    private String[] infos = {"我来自中国的一个小乡村,地处湖南省","我来自中国的一个大城市,名叫上海,人们称作魔都"
            ,"我来自东北,家住大囤里,一口大碴子话"};
    @GetMapping("saveUser")
    public String saveUser(){
        Random random = new Random();
        List<User> users = new ArrayList<>();
       /* for(int i =0;i<20;i++){
            User user = new User(i,random.nextInt(40)+i,names[random.nextInt(9)] ,
                            infos[random.nextInt(2)] );
            users.add(user);
        }*/
        User user1 = new User(20,21,"上海的小李","上周的天气不错,海边风大");
        User user2 = new User(21,21,"上海的小王","昨天的天气不错,海边风大");
        User user3 = new User(22,21,"浙江的老王","昨天的天气不错,海边风大");
        User user4 = new User(23,21,"苏州的小赵","上周的天气不错,海边风大");
        users.add(user1);
        users.add(user2);
        users.add(user3);
        users.add(user4);
        Iterable<User> users1 = userService.saveAll(users);
        return "save successfully";
    }
    @GetMapping("getDataById/{id}")
    public   Optional<User> getDataById(@PathVariable("id") Integer id){
        Optional<User> user = userService.findById(id);
        System.out.println("get by id user:" + user);
        return user;
    }
    // 分页查询
    @GetMapping("getAllDataByPage")
    public   Page<User> getAllDataByPage(){
        Pageable page = PageRequest.of(0,10, Sort.Direction.ASC,"id");
        Page<User> allUser =userService.findAll(page);
        System.out.println("getAllDataByPage:" + allUser);
        return allUser;
    }
    //根据名字查询
    @GetMapping("getDataByName/{name}")
    public List<User> getDataByName(@PathVariable("name") String name){
        return userService.findByName(name);
    }
    @GetMapping("getDataByNameandInfo/{info}")
    //根据名字查询
    public List<User> getDataByInfo(@PathVariable("info") String info){
        return userService.findByInfo(info);
    }
    // 查询高亮显示
    @GetMapping("getHighByUser")
    public  List<User> getHighByUser(@PathParam("kw") String kw){
        System.out.println("kw = " + kw);
        //根据一个值查询多个字段,并高亮显示,这里的查询是取并集,
        //即多个字段只要有一个字段满足即可
        //需要查询的字段
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery()
                .should(QueryBuilders.matchQuery("info",kw))
                .should(QueryBuilders.matchQuery("name",kw));
        //构建高亮查询
        NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
                            .withQuery(boolQueryBuilder)
                            .withHighlightFields(
                                    new HighlightBuilder.Field("info"),
                                    new HighlightBuilder.Field("name"))
                            .withHighlightBuilder(new HighlightBuilder()
                                     .preTags("<span style='color:yellow'>")
                                     .postTags("</span>"))
                            .build();
        //查询
         SearchHits<User> search = restTemplate.search(searchQuery,User.class);
//  SearchHits<User> ==== for(...user ) -- high light name : old name ,  high light info  : old info
        // new user ---- List<User>
         //得到查询返回的内容
        List<SearchHit<User>> searchHits = search.getSearchHits();//getSearchHits();
        //设置一个最后需要返回的实体类集合
        List<User> userList = new ArrayList<>();
        for(SearchHit<User> searchHit:searchHits){
          //高亮内容
          Map<String ,List<String>> highlightFields = searchHit.getHighlightFields();
          //将高亮的内容填充到content中
            String name = highlightFields.get("name") ==null ?searchHit.getContent().getName() :highlightFields.get("name").get(0);
            String info = highlightFields.get("info") ==null ?searchHit.getContent().getName() :highlightFields.get("info").get(0);
            searchHit.getContent().setName(name );
            searchHit.getContent().setInfo(info);
            //放到实体类中
            userList.add(searchHit.getContent());
        }
        return  userList;
    }
    @GetMapping("getHighByPage/{name}/{info}/{pageNum}")
    public  Map<String,Object> getHighByPage(@PathVariable("name") String name,
                                     @PathVariable("info") String info ,
                                     @PathVariable("pageNum")Integer pageNum){
       return userService2.getUserList(name,info,pageNum);
    }
}
相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
目录
相关文章
|
1天前
|
自然语言处理 搜索推荐 Java
SpringBoot 搜索引擎 海量数据 Elasticsearch-7 es上手指南 毫秒级查询 包括 版本选型、操作内容、结果截图(一)
SpringBoot 搜索引擎 海量数据 Elasticsearch-7 es上手指南 毫秒级查询 包括 版本选型、操作内容、结果截图
9 0
|
1天前
|
存储 自然语言处理 搜索推荐
SpringBoot 搜索引擎 海量数据 Elasticsearch-7 es上手指南 毫秒级查询 包括 版本选型、操作内容、结果截图(二)
SpringBoot 搜索引擎 海量数据 Elasticsearch-7 es上手指南 毫秒级查询 包括 版本选型、操作内容、结果截图(二)
10 0
|
2月前
|
网络协议 Java API
SpringBoot整合Elasticsearch-Rest-Client、测试保存、复杂检索
这篇文章介绍了如何在SpringBoot中整合Elasticsearch-Rest-Client,并提供了保存数据和进行复杂检索的测试示例。
SpringBoot整合Elasticsearch-Rest-Client、测试保存、复杂检索
|
2月前
|
自然语言处理 Java 关系型数据库
ElasticSearch 实现分词全文检索 - SpringBoot 完整实现 Demo 附源码【完结篇】
ElasticSearch 实现分词全文检索 - SpringBoot 完整实现 Demo 附源码【完结篇】
35 0
|
2月前
|
自然语言处理 Java 索引
ElasticSearch 实现分词全文检索 - Java SpringBoot ES 文档操作
ElasticSearch 实现分词全文检索 - Java SpringBoot ES 文档操作
33 0
|
2月前
|
自然语言处理 Java 索引
ElasticSearch 实现分词全文检索 - Java SpringBoot ES 索引操作
ElasticSearch 实现分词全文检索 - Java SpringBoot ES 索引操作
36 0
|
3月前
|
Java 索引 Spring
教程:Spring Boot中集成Elasticsearch的步骤
教程:Spring Boot中集成Elasticsearch的步骤
|
4月前
|
存储 搜索推荐 Java
Spring Boot与Elasticsearch的集成应用
Spring Boot与Elasticsearch的集成应用
|
4月前
|
搜索推荐 Java 索引
教程:Spring Boot中集成Elasticsearch的步骤
教程:Spring Boot中集成Elasticsearch的步骤
|
4月前
|
Java
springboot集成ElasticSearch(支持集群)
springboot集成ElasticSearch(支持集群)
250 0