java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > SpringBoot接入Elasticsearch

SpringBoot接入Elasticsearch完整教程

作者:奋力向前123

文章浏览阅读306次,点赞7次,收藏3次。SpringBoot 接入 Elasticsearch 完整教程

版本说明:

一、前置准备

  1. 部署 Elasticsearch(单机 / 集群),ES 8 默认开启 HTTPS + 账号认证,开发可临时关闭安全
  2. 中文检索建议安装 IK 分词器(版本必须和 ES 完全一致)
  3. 确保 SpringBoot、Spring Data ES、ES 服务端 版本兼容(版本不匹配是最常见报错)

二、Maven 依赖(SpringBoot3 + ES8 推荐)

<!-- Spring Data Elasticsearch 自动引入新版Java API Client -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<!-- lombok 可选,简化实体类 -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>

SpringBoot2.7 + ES7 旧项目:同样使用 starter,底层自动使用 RestHighLevelClient(不再推荐新项目使用)

三、application.yml 配置

spring:
  elasticsearch:
    uris: http://127.0.0.1:9200 #集群多个节点逗号分隔
    # ES开启认证时配置账号密码
    # username: elastic
    # password: elastic
    connection-timeout: 10s
    socket-timeout: 30s
# 调试:打印ES请求DSL
logging:
  level:
    org.springframework.data.elasticsearch: DEBUG

四、定义 ES 实体(Document 映射索引)

import lombok.Data;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
@Data
// indexName:索引名(小写,不能大写)createIndex=true项目启动自动创建索引
@Document(indexName = "product", createIndex = true)
public class ProductDoc {
    // @Id 对应ES文档 _id
    @Id
    private Long id;
    // Text:分词,全文检索;ik_max_word 细粒度分词,ik_smart粗粒度
    @Field(type = FieldType.Text, analyzer = "ik_max_word", searchAnalyzer = "ik_smart")
    private String name;
    // Keyword:不分词,精确匹配、筛选、聚合
    @Field(type = FieldType.Keyword)
    private String category;
    @Field(type = FieldType.Double)
    private Double price;
    @Field(type = FieldType.Text, analyzer = "ik_max_word")
    private String desc;
}

注解说明:

方式 1:ElasticsearchRepository(简单 CRUD)

1. 创建 Repository 接口

import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
// 泛型:实体类,主键类型
public interface ProductRepository extends ElasticsearchRepository<ProductDoc, Long> {
    // 【方法名自动推导查询】根据名称分词查询
    List<ProductDoc> findByName(String name);
    // 自定义DSL语句查询
    // @Query("{\"match\": {\"name\": \"?0\"}}")
    // List<ProductDoc> searchName(String keyword);
}

2. 使用示例

@Service
@RequiredArgsConstructor
public class ProductService {
    private final ProductRepository productRepository;
    // 新增/全量更新(id存在则覆盖,不存在新增)
    public void save(ProductDoc doc) {
        productRepository.save(doc);
    }
    // 根据id查询
    public Optional<ProductDoc> findById(Long id) {
        return productRepository.findById(id);
    }
    // 删除
    public void delete(Long id) {
        productRepository.deleteById(id);
    }
    // 分页
    public Page<ProductDoc> page(String keyword, int page, int size) {
        Pageable pageable = PageRequest.of(page, size);
        return productRepository.findByName(keyword, pageable);
    }
}

✅ 优点:代码极简;❌ 缺点:复杂 bool 组合、高亮、聚合不好实现

方式 2:ElasticsearchOperations(推荐,复杂查询)

Spring Data ES5.x 推荐注入 ElasticsearchOperations(替代旧版 ElasticsearchRestTemplate),支持构建原生 DSL、分页、排序、高亮、聚合Spring

@Service
@RequiredArgsConstructor
public class ProductEsService {
    private final ElasticsearchOperations esOperations;
    // 1. 新增文档
    public ProductDoc saveDoc(ProductDoc doc) {
        return esOperations.save(doc);
    }
    // 2. 根据id查询
    public ProductDoc getById(Long id) {
        return esOperations.get(String.valueOf(id), ProductDoc.class);
    }
    // 3. 删除文档
    public void deleteDoc(Long id) {
        esOperations.delete(String.valueOf(id), ProductDoc.class);
    }
    // 4. 复杂组合查询:关键词检索 + 分类筛选 + 价格区间 + 分页 + 高亮
    public SearchHits<ProductDoc> search(String keyword, String category, Double minPrice, int pageNum, int pageSize) {
        // 构建Bool查询
        BoolQuery boolQuery = BoolQuery.builder()
                // must:必须匹配(分词检索商品名)
                .must(m -> m.match(ma -> ma.field("name").query(keyword)))
                // filter:过滤,不计算相关度
                .filter(f -> f.term(t -> t.field("category").value(category)))
                .filter(f -> f.range(r -> r.field("price").gte(JsonData.of(minPrice))))
                .build();
        // 高亮配置
        HighlightOptions highlight = HighlightOptions.builder()
                .field("name", h -> h.preTags("<em>").postTags("</em>"))
                .build();
        NativeSearchQuery searchQuery = NativeSearchQueryBuilder()
                .withQuery(boolQuery)
                .withHighlightOptions(highlight)
                .withPageable(PageRequest.of(pageNum, pageSize)) // page从0开始
                .withSort(Sort.by(Sort.Direction.DESC, "price"))
                .build();
        // 执行查询
        return esOperations.search(searchQuery, ProductDoc.class);
    }
}

方式 3:原生 ElasticsearchClient(官方底层客户端,极致灵活)

适合聚合、向量检索、ES 新特性,完全对齐官方 DSL,强类型编译校验CSDN博...

@Service
@RequiredArgsConstructor
public class ProductNativeService {
    private final ElasticsearchClient esClient;
    // 新增文档
    public void insert(ProductDoc doc) throws IOException {
        esClient.index(i -> i
                .index("product")
                .id(doc.getId().toString())
                .document(doc)
        );
    }
    // match分词查询
    public SearchResponse<ProductDoc> search(String keyword) throws IOException {
        return esClient.search(s -> s
                .index("product")
                .query(q -> q.match(m -> m.field("name").query(keyword))),
                ProductDoc.class
        );
    }
}

五、常用高级操作

1. 索引管理(创建 / 删除索引)

// 注入 ElasticsearchOperations
IndexOperations indexOps = esOperations.indexOps(ProductDoc.class);
// 判断索引是否存在
boolean exist = indexOps.exists();
// 删除索引
if(exist){
    indexOps.delete();
}
// 创建索引+自动映射mapping
indexOps.create();
indexOps.putMapping();

2. 批量导入(Bulk 批量插入,大数据必用)

List<ProductDoc> list = new ArrayList<>();
// 封装多条数据
esOperations.save(list);

3. 高亮结果解析

search 返回 SearchHits<ProductDoc>,遍历 SearchHit 获取 getHighlightFields() 替换原始文本

六、常见踩坑总结

  1. 版本不匹配:90% 报错来源,严格对齐 SpringBoot → Spring Data ES → ES 服务端版本
  2. 索引名不能大写,ES 底层全小写
  3. Text 字段用于分词搜索,Keyword 用于筛选、分组、精确匹配,不要混用
  4. ES8 默认开启 SSL 和账号认证,开发环境关闭安全,生产务必开启
  5. 深分页(from+size 超过 10000)会报错,需使用 scroll 滚动分页 /search_after
  6. 数据库和 ES 数据一致性:通过 MQ 双写、binlog 同步(Canal)保证最终一致性,不要依赖事务
  7. IK 分词器版本必须和 ES 版本一致,否则 ES 启动失败

以上就是SpringBoot接入Elasticsearch完整教程的详细内容,更多关于SpringBoot接入Elasticsearch的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文