spring boot 2.7.X下使用elastic

说明:
由于elastic 更新较快,这里只介绍spring boot 集成的elastic7.17.4 ,如果想直接使用elastic8,推荐你再搜搜别的
本文章大概可以坚持到2024年(如果更新会往后推)
没有2.7版本可以试着升一下spring boot2升级至2.7.3环境配置

这里使用的是ElasticsearchRestTemplate

RestHighLevelClient 已弃用
ElasticsearchRepository已弃用

1. 引入elastic

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
	<version>2.7.3</version>
</dependency>

2. Yml配置

注意了,当前版本就是这个,原来的版本要注意会存在多字段

spring:
  elasticsearch:
    uris: 192.168.2.91:9200
    #username:
    #password:
    #connection-timeout: 1
    #read-timeout: 30 默认30

3. 创建MyUser实体类

需要注意大小写以及下划线转换

import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;

/**
 * @author king
 */
@Data
@Document(indexName = "my_user")
public class MyUser {
    @Id
    private String id;
    private String username;
    private String password;
    private String realname;
    private String nickname;
    private String file;
	// 这里没用到
    public MyUser(String id, String username, String password,String realname, String nickname, String file) {
        this.id = id;
        this.username = username;
        this.password = password;
        this.realname = realname;
        this.nickname = nickname;
        this.file = file;
    }
    public MyUser() {
    }
}

4. 创建 service

这里贴一个我自己写的util,可以直接用在service里

import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.IndexOperations;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Collection;

/**
 * @author king
 * 2022-08-23
 * 此方法适用于 spring boot 2.7.X 以及spring boot 当前版本集成下的elastic-7.17.4
 * 涵盖sprng-data-elasticsearch-4.4.2
 */
@Component
public class ElasticUtils {
    @Resource
    ElasticsearchRestTemplate elasticsearchRestTemplate;

    /**
     * 新增索引(表)
     */
    public <T> Boolean put(T entity) {
        IndexOperations indexOperations = elasticsearchRestTemplate.indexOps(entity.getClass());
        return indexOperations.create();
    }

    /**
     * 判断索引是否存在
     */
    public <T> Boolean exists(T entity) {
        IndexOperations indexOperations = elasticsearchRestTemplate.indexOps(entity.getClass());
        return indexOperations.exists();
    }

    /**
     * 删除索引
     */
    public <T> Boolean delete(T entity) {
        IndexOperations indexOperations = elasticsearchRestTemplate.indexOps(entity.getClass());
        return indexOperations.delete();
    }

    /**
     * 修整索引字段(与实体类保持一致,一般为增加,减少字段未测试)
     */
    public <T> Boolean mapping(T entity) {
        IndexOperations indexOperations = elasticsearchRestTemplate.indexOps(entity.getClass());
        return indexOperations.putMapping();
    }
    /**
     * 插入
     */
    public <T> T save(T entity) {
        return elasticsearchRestTemplate.save(entity);
    }
    /**
     * 批量插入
     */
    public Iterable saveBatch(Collection collectors) {
        return elasticsearchRestTemplate.save(collectors);
    }
    /**
     * 根据主键查询
     */
    public <T> Object get(String id, T entity) {
        return elasticsearchRestTemplate.get(id, entity.getClass());
    }
    /**
     * 根据主键删除
     */
    public <T> String delete(String id, T entity) {
        return elasticsearchRestTemplate.delete(id, entity.getClass());
    }
    /**
     * 多条件查询
     */
    public <T> SearchHits<?> search(T entity, NativeSearchQueryBuilder queryBuilder) {
        IndexCoordinates indexCoordinatesFor = elasticsearchRestTemplate.getIndexCoordinatesFor(entity.getClass());
        return elasticsearchRestTemplate.search(queryBuilder.build(), entity.getClass(), indexCoordinatesFor);
    }
}

5. 复杂查询

这里先介绍三个query
TermQueryBuilder 精确匹配,MatchPhraseQueryBuilder 模糊匹配,BoolQueryBuilder布尔查询,布尔查询可以嵌套 前边两个条件

// 精确匹配,对中文不友好(仅一个字符),没有分词器概念,查询条件为一个字符时可以多重匹配,多个字符类似于mysql 的等于条件
//TermQueryBuilder
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("username", "wangw");
// 模糊匹配,存在分词器概念,可将查询条件分成多个字符进行查询
//MatchPhraseQueryBuilder
MatchPhraseQueryBuilder matchPhraseQueryBuilder = QueryBuilders.matchPhraseQuery("realname", "张");

// 布尔查询,可以将上述的各种条件添加入bool中作为多条件查询
BoolQueryBuilder

BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
// 必须条件 and
boolQueryBuilder.must(termQueryBuilder);
// 只要满足即可 or
boolQueryBuilder.should(termQueryBuilder);

这里贴一个查询实例:

 public void test() {
	MatchPhraseQueryBuilder termQueryBuilder = QueryBuilders.matchPhraseQuery("nickname", "可恶");
    MatchPhraseQueryBuilder matchPhraseQueryBuilder = QueryBuilders.matchPhraseQuery("realname", "张");
    BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
    boolQueryBuilder.must(termQueryBuilder);
    boolQueryBuilder.should(termQueryBuilder);
// 查询条件
    NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder()
            .withQuery(boolQueryBuilder)
            .withSourceFilter(new FetchSourceFilterBuilder().build())
            // 高亮
            .withHighlightFields(
                    new HighlightBuilder.Field("nickname"),
                    new HighlightBuilder.Field("realname")
            )
            // 去除查询结果 只取聚合查询的结果
            // 分页
            .withFields()
            .withPageable(PageRequest.of(0, 10));
IndexCoordinates indexCoordinatesFor = elasticsearchRestTemplate.getIndexCoordinatesFor(MyUser.class);
SearchHits<MyUser> search = elasticsearchRestTemplate.search(queryBuilder.build(), MyUser.class, indexCoordinatesFor);

    List<SearchHit<MyUser>> searchHits = search.getSearchHits();
    List<MyUser> posts = new ArrayList<>();
    //遍历返回的内容进行处理
    for(SearchHit<MyUser> searchHit:searchHits){
        //高亮的内容
        Map<String, List<String>> highlightFields = searchHit.getHighlightFields();
        //将高亮的内容填充到content中
        searchHit.getContent().setNickname(highlightFields.get("nickname")==null ? searchHit.getContent().getNickname():highlightFields.get("nickname").get(0));
        searchHit.getContent().setRealname(highlightFields.get("realname")==null ? searchHit.getContent().getRealname():highlightFields.get("realname").get(0));
        //放到实体类中
        posts.add(searchHit.getContent());
    }
    System.out.println(posts);
}
  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

vace cc

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值