java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > SpringBoot Elasticsearch8.0集成

SpringBoot与Elasticsearch8.0集成的实现步骤

作者:亚历克斯神

本文介绍了SpringBoot与Elasticsearch8.0的集成方法和最佳实践,详细探讨了Elasticsearch8.0的安全增强、性能优化、API改进等新特性,下面就一起来了解一下

前言

Elasticsearch 是一个功能强大的分布式搜索引擎,被广泛应用于日志分析、全文搜索、监控等场景。Elasticsearch 8.0 带来了许多新特性,如安全增强、性能优化、API 改进等。本文将深入探讨 Spring Boot 与 Elasticsearch 8.0 的集成方法和最佳实践,帮助你构建更高效、更可靠的搜索应用。

1. Elasticsearch 8.0 新特性

1.1 安全增强

Elasticsearch 8.0 强化了安全性,默认启用了安全功能,包括:

1.2 性能优化

Elasticsearch 8.0 在性能方面进行了多项优化:

1.3 API 改进

Elasticsearch 8.0 对 API 进行了改进:

1.4 其他新特性

2. Spring Boot 与 Elasticsearch 集成

2.1 添加依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
<!-- 可选:使用 Elasticsearch 高级客户端 -->
<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
    <version>8.0.0</version>
</dependency>

2.2 配置 Elasticsearch

spring:
  elasticsearch:
    uris: https://localhost:9200
    username: elastic
    password: your-password
    connection-timeout: 10000
    socket-timeout: 10000

2.3 Elasticsearch 客户端配置

@Configuration
public class ElasticsearchConfig {
    @Bean
    public RestHighLevelClient elasticsearchClient() {
        ClientConfiguration clientConfiguration = ClientConfiguration.builder()
            .connectedTo("localhost:9200")
            .withBasicAuth("elastic", "your-password")
            .withConnectTimeout(Duration.ofSeconds(10))
            .withSocketTimeout(Duration.ofSeconds(10))
            .withTls()
            .build();
        return RestClients.create(clientConfiguration).rest();
    }
}

3. 实体映射

3.1 基本实体映射

@Document(indexName = "users")
public class User {
    @Id
    private String id;
    @Field(type = FieldType.Text)
    private String name;
    @Field(type = FieldType.Integer)
    private int age;
    @Field(type = FieldType.Text, analyzer = "ik_max_word")
    private String address;
    @Field(type = FieldType.Date)
    private LocalDateTime createdAt;
    // getters and setters
}

3.2 复杂实体映射

@Document(indexName = "products")
public class Product {
    @Id
    private String id;
    @Field(type = FieldType.Text)
    private String name;
    @Field(type = FieldType.Double)
    private double price;
    @Field(type = FieldType.Keyword)
    private String category;
    @Field(type = FieldType.Nested)
    private List<Review> reviews;
    @Field(type = FieldType.Object)
    private Manufacturer manufacturer;
    // getters and setters
}
public class Review {
    @Field(type = FieldType.Integer)
    private int rating;
    @Field(type = FieldType.Text)
    private String comment;
    @Field(type = FieldType.Date)
    private LocalDateTime createdAt;
    // getters and setters
}
public class Manufacturer {
    @Field(type = FieldType.Text)
    private String name;
    @Field(type = FieldType.Text)
    private String country;
    // getters and setters
}

4. 仓库接口

4.1 基本仓库接口

public interface UserRepository extends ElasticsearchRepository<User, String> {
    // 基于方法名的查询
    List<User> findByName(String name);
    List<User> findByAgeBetween(int minAge, int maxAge);
    List<User> findByNameAndAge(String name, int age);
}

4.2 自定义查询

public interface ProductRepository extends ElasticsearchRepository<Product, String> {
    // 使用 @Query 注解
    @Query("{\"bool\": {\"must\": [{\"match\": {\"name\": \"?0\"}}, {\"range\": {\"price\": {\"lte\": ?1}}}]}}")
    List<Product> findByNameAndPriceLessThanEqual(String name, double price);
    // 基于方法名的复杂查询
    List<Product> findByCategoryAndReviewsRatingGreaterThan(String category, int rating);
}

5. 操作示例

5.1 基本操作

@Service
public class UserService {
    private final UserRepository userRepository;
    @Autowired
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
    // 保存用户
    public User saveUser(User user) {
        return userRepository.save(user);
    }
    // 根据 ID 查询用户
    public Optional<User> getUserById(String id) {
        return userRepository.findById(id);
    }
    // 查询所有用户
    public Iterable<User> getAllUsers() {
        return userRepository.findAll();
    }
    // 删除用户
    public void deleteUser(String id) {
        userRepository.deleteById(id);
    }
    // 根据名称查询用户
    public List<User> getUsersByName(String name) {
        return userRepository.findByName(name);
    }
}

5.2 高级查询

@Service
public class ProductService {
    private final ProductRepository productRepository;
    private final ElasticsearchOperations elasticsearchOperations;
    @Autowired
    public ProductService(ProductRepository productRepository, ElasticsearchOperations elasticsearchOperations) {
        this.productRepository = productRepository;
        this.elasticsearchOperations = elasticsearchOperations;
    }
    // 复杂查询
    public List<Product> searchProducts(String keyword, double maxPrice, String category) {
        NativeSearchQuery query = new NativeSearchQueryBuilder()
            .withQuery(QueryBuilders.boolQuery()
                .must(QueryBuilders.multiMatchQuery(keyword, "name", "description"))
                .filter(QueryBuilders.rangeQuery("price").lte(maxPrice))
                .filter(QueryBuilders.termQuery("category", category)))
            .withSort(SortBuilders.fieldSort("price").order(SortOrder.ASC))
            .withPageable(PageRequest.of(0, 10))
            .build();
        return elasticsearchOperations.search(query, Product.class)
            .stream()
            .map(SearchHit::getContent)
            .collect(Collectors.toList());
    }
}

5.3 聚合操作

@Service
public class AnalyticsService {
    private final ElasticsearchOperations elasticsearchOperations;
    
    @Autowired
    public AnalyticsService(ElasticsearchOperations elasticsearchOperations) {
        this.elasticsearchOperations = elasticsearchOperations;
    }
    
    // 按类别聚合产品
    public Map<String, Long> getProductCountByCategory() {
        NativeSearchQuery query = new NativeSearchQueryBuilder()
            .withQuery(QueryBuilders.matchAllQuery())
            .withAggregations(AggregationBuilders.terms("byCategory").field("category"))
            .build();
        
        SearchHits<Product> searchHits = elasticsearchOperations.search(query, Product.class);
        Terms terms = searchHits.getAggregations().get("byCategory");
        
        Map<String, Long> result = new HashMap<>();
        for (Terms.Bucket bucket : terms.getBuckets()) {
            result.put(bucket.getKeyAsString(), bucket.getDocCount());
        }
        
        return result;
    }
    
    // 计算平均价格
    public double getAveragePrice() {
        NativeSearchQuery query = new NativeSearchQueryBuilder()
            .withQuery(QueryBuilders.matchAllQuery())
            .withAggregations(AggregationBuilders.avg("averagePrice").field("price"))
            .build();
        
        SearchHits<Product> searchHits = elasticsearchOperations.search(query, Product.class);
        Avg avg = searchHits.getAggregations().get("averagePrice");
        
        return avg.getValue();
    }
}

6. 批量操作

6.1 批量索引

@Service
public class BulkService {
    private final ElasticsearchOperations elasticsearchOperations;
    @Autowired
    public BulkService(ElasticsearchOperations elasticsearchOperations) {
        this.elasticsearchOperations = elasticsearchOperations;
    }
    // 批量索引文档
    public void bulkIndex(List<User> users) {
        elasticsearchOperations.bulkIndex(users, IndexCoordinates.of("users"));
    }
    // 批量删除文档
    public void bulkDelete(List<String> ids) {
        List<DeleteQuery> deleteQueries = ids.stream()
            .map(id -> {
                DeleteQuery deleteQuery = new DeleteQuery();
                deleteQuery.setId(id);
                return deleteQuery;
            })
            .collect(Collectors.toList());
        elasticsearchOperations.bulkDelete(deleteQueries, User.class, IndexCoordinates.of("users"));
    }
}

7. 性能优化

7.1 索引优化

  1. 合理设计索引:根据业务需求设计合理的索引结构
  2. 使用合适的字段类型:选择合适的字段类型,如 keyword、text、numeric 等
  3. 配置分析器:为文本字段配置合适的分析器
  4. 设置合理的分片和副本:根据数据量和查询需求设置分片和副本数量

7.2 查询优化

  1. 使用过滤器:对不需要评分的查询使用过滤器
  2. 避免深度分页:使用 scroll API 或 search after 进行深度分页
  3. 使用聚合缓存:对频繁使用的聚合启用缓存
  4. 优化查询语句:避免复杂的嵌套查询

7.3 写入优化

  1. 使用批量操作:使用 bulk API 进行批量写入
  2. 合理设置刷新间隔:根据业务需求设置合适的刷新间隔
  3. 使用异步写入:使用异步 API 进行写入操作
  4. 避免实时索引:对非实时数据使用延迟索引

8. 最佳实践

8.1 代码组织

// 推荐的代码组织结构
com.example
├── entity/          // 实体类
├── repository/      // 仓库接口
├── service/         // 业务逻辑
├── controller/      // 控制器
└── config/          // 配置类

8.2 错误处理

@Service
public class UserService {
    private final UserRepository userRepository;
    @Autowired
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
    public User getUserById(String id) {
        try {
            return userRepository.findById(id)
                .orElseThrow(() -> new EntityNotFoundException("User not found"));
        } catch (ElasticsearchException e) {
            throw new RuntimeException("Error querying Elasticsearch", e);
        }
    }
}

8.3 监控与日志

management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics,prometheus
  endpoint:
    health:
      show-details: always
logging:
  level:
    org.elasticsearch.client: debug

9. 案例分析

9.1 全文搜索系统

某电商平台使用 Elasticsearch 实现全文搜索功能,主要包括:

  1. 商品索引:将商品信息索引到 Elasticsearch
  2. 全文搜索:支持商品名称、描述的全文搜索
  3. 过滤和排序:支持按价格、类别等过滤和排序
  4. 聚合分析:提供商品分类统计、价格分布等分析

9.2 日志分析系统

某企业使用 Elasticsearch 实现日志分析系统,主要包括:

  1. 日志收集:使用 Logstash 收集应用日志
  2. 日志索引:将日志索引到 Elasticsearch
  3. 日志查询:支持按时间、级别、关键词等查询日志
  4. 监控告警:基于日志内容设置告警规则

9.3 实时数据分析

某金融机构使用 Elasticsearch 实现实时数据分析,主要包括:

  1. 数据采集:实时采集交易数据
  2. 数据索引:将数据索引到 Elasticsearch
  3. 实时查询:支持实时查询和分析
  4. 可视化:使用 Kibana 可视化数据

10. 未来趋势

10.1 向量搜索

Elasticsearch 8.0 开始支持向量搜索,这将为 AI 应用提供强大的支持,例如:

10.2 边缘计算

Elasticsearch 正在向边缘计算扩展,支持在边缘设备上部署轻量级实例,实现:

10.3 AI 集成

Elasticsearch 与 AI 技术的集成将成为未来的趋势,例如:

11. 总结

Spring Boot 与 Elasticsearch 8.0 的集成是构建高性能搜索应用的重要组成部分。通过本文的介绍,你应该对 Spring Boot 与 Elasticsearch 8.0 的集成方法和最佳实践有了更深入的了解。

Elasticsearch 8.0 的新特性为我们提供了更强大的功能和更好的性能,通过合理使用这些特性,我们可以构建更高效、更可靠的搜索应用。

结语

Elasticsearch 是一个功能强大的搜索引擎,它为我们提供了丰富的功能和灵活的 API。Spring Boot 与 Elasticsearch 的集成使得我们可以更方便地使用 Elasticsearch 的功能,构建各种搜索和分析应用。

随着 Elasticsearch 的不断发展,它将为我们提供更多强大的功能,帮助我们解决各种复杂的搜索和分析问题。

到此这篇关于SpringBoot与Elasticsearch8.0集成的文章就介绍到这了,更多相关SpringBoot Elasticsearch8.0集成内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

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