SpringBoot + Elasticsearch7.6实现简单查询及高亮分词查询

我是程序汪

共 2455字,需浏览 5分钟

 · 2022-03-02

前言

该文章需要提前准备好Elasticsearch7.6以及ik分词器的环境,如果还没准备好的可以看看

https://blog.csdn.net/weixin_44102992/article/details/107954129

集成环境准备

1.导入spring-data-elasticsearch依赖

版本需要与Elasticsearch一致,还需要注意自己的springboot版本是否支持

本文springboot为2.3,依赖也为2.3,elasticsearch为7.6.2

<dependency>
  <groupId>org.springframework.datagroupId>
  <artifactId>spring-data-elasticsearchartifactId>
  <version>${version}.RELEASEversion>
dependency>

2.elasticsearch配置文件

因为原来的配置不支持了

配置文件如下:

@Configuration
public class EsConf {
    @Value("${elasticSearch.url}")
    private String edUrl;

    //localhost:9200 写在配置文件中就可以了
    @Bean
    RestHighLevelClient client() {
        ClientConfiguration clientConfiguration = ClientConfiguration.builder()
                .connectedTo(edUrl)//elasticsearch地址
                .build();

        return RestClients.create(clientConfiguration).rest();
    }
}

3.实体类准备

关于实体类中的几个注解,不清楚的可以去查看文档,这里不过多介绍了

@Data
@Document(indexName = "user")//索引名称 建议与实体类一致
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;
}

4.Elasticsearch Service准备

ElasticsearchRepository<,>第一个就是所准备的实体类,第二个是id的类型

继承完这个会提供最基本的增删改查方法,也可以自己定义一些,自己定义的方法命名需要符合规则,并不需要自己去实现

public interface EsUserService extends ElasticsearchRepository<User,Integer{
    //根据name查询
    List findByName(String name);

    //根据name和info查询
    List findByNameAndInfo(String name,String info);
}

简单查询

这里直接使用假数据并没有连接数据库,还需要注意几个点:

  1. elasticsearchTemplate需要采用ElasticsearchRestTemplate 原来的已经过时了
  2. elasticsearch的mapping没有自动生成,这导致了我们在实体类中指定的分词器没有生效,所以我在导入数据的同时,手动导入了mapping
  3. LogAnnotation是我自定义的注解,大家可以直接去掉

controller如下:

@RestController
public class EsController {
    @Autowired
    private ElasticsearchRestTemplate elasticsearchTemplate;
    @Autowired
    private EsUserService esUserService;

    private String[] names={"诸葛亮","曹操","李白","韩信","赵云","小乔","狄仁杰","李四","诸小明","王五"};
    private String[] infos={"我来自中国的一个小乡村,地处湖南省","我来自中国的一个大城市,名叫上海,人们称作魔都"
            ,"我来自东北,家住大囤里,一口大碴子话"};
    @LogAnnotation(requestRemark = "存数据")
    @GetMapping("saveUser")
    public ResultVO saveUser(){
     //添加索引mapping    索引会自动创建但mapping自只用默认的这会导致分词器不生效 所以这里我们手动导入mapping
        elasticsearchTemplate.putMapping(User.class);
        Random random = new Random();
        List users = new ArrayList<>();
        for (int i=0;i<20;i++){
            User user = new User();
            user.setId(i);
            user.setName(names[random.nextInt(9)]);
            user.setAge(random.nextInt(40)+i);
            user.setInfo(infos[random.nextInt(2)]);
            users.add(user);
        }
        Iterable users1 = esUserService.saveAll(users);
        return new ResultVO(users1);
    }

    @LogAnnotation(requestRemark = "根据id查询数据")
    @GetMapping("getDataById")
    public ResultVO getDataById(Integer id){
        return new ResultVO(esUserService.findById(id));
    }

    @LogAnnotation(requestRemark = "分页查询所有数据")
    @GetMapping("getAllDataByPage")
    public ResultVO getAllDataByPage(){
        //本该传入page和size,这里为了方便就直接写死了
        Pageable page = PageRequest.of(0,10, Sort.Direction.ASC,"id");
        Page all = esUserService.findAll(page);
        return new ResultVO(all.getContent());
    }

    @LogAnnotation(requestRemark = "根据名字查询")
    @GetMapping("getDataByName")
    public ResultVO getDataByName(String name){
        return new ResultVO(esUserService.findByName(name));
    }

    @LogAnnotation(requestRemark = "根据名字和介绍查询")
    @GetMapping("getDataByNameAndInfo")
    public ResultVO getDataByNameAndInfo(String name,String info){
        //这里是查询两个字段取交集,即代表两个条件需要同时满足
        return new ResultVO(esUserService.findByNameAndInfo(name,info));
    }
}

测试结果:

分词高亮查询

    @LogAnnotation(requestRemark = "查询高亮显示")
    @GetMapping("getHightByUser")
    public ResultVO getHightByUser(String value){
        //根据一个值查询多个字段  并高亮显示  这里的查询是取并集,即多个字段只需要有一个字段满足即可
        //需要查询的字段
        BoolQueryBuilder boolQueryBuilder= QueryBuilders.boolQuery()
                .should(QueryBuilders.matchQuery("info",value))
                .should(QueryBuilders.matchQuery("name",value));
  //构建高亮查询
        NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(boolQueryBuilder)
                .withHighlightFields(
                        new HighlightBuilder.Field("info")
                        ,new HighlightBuilder.Field("name"))
                .withHighlightBuilder(new HighlightBuilder().preTags("").postTags(""))
                .build();
        //查询
        SearchHits search = elasticsearchTemplate.search(searchQuery, User.class);
        //得到查询返回的内容
        List> searchHits = search.getSearchHits();
        //设置一个最后需要返回的实体类集合
        List users = new ArrayList<>();
        //遍历返回的内容进行处理
        for(SearchHit searchHit:searchHits){
            //高亮的内容
            Map> highlightFields = searchHit.getHighlightFields();
            //将高亮的内容填充到content中
            searchHit.getContent().setName(highlightFields.get("name")==null ? searchHit.getContent().getName():highlightFields.get("name").get(0));
            searchHit.getContent().setInfo(highlightFields.get("info")==null ? searchHit.getContent().getInfo():highlightFields.get("info").get(0));
            //放到实体类中
            users.add(searchHit.getContent());
        }
        return new ResultVO(users);
    }

测试结果:

来源:blog.csdn.net/weixin_44102992/article/

details/108033164

程序汪资料链接

程序汪接的7个私活都在这里,经验整理

Java项目分享 最新整理全集,找项目不累啦 06版

堪称神级的Spring Boot手册,从基础入门到实战进阶

卧槽!字节跳动《算法中文手册》火了,完整版 PDF 开放下载!

卧槽!阿里大佬总结的《图解Java》火了,完整版PDF开放下载!

字节跳动总结的设计模式 PDF 火了,完整版开放下载!

欢迎添加程序汪个人微信 itwang008  进粉丝群或围观朋友圈

浏览 14
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报