Java与Elasticsearch集成详解,以及利用指南

打印 上一主题 下一主题

主题 1037|帖子 1037|积分 3111

Java与Elasticsearch集成详解

1. 环境配置

首先,你需要在Maven项目中添加Elasticsearch Java客户端依赖:
  1. <dependencies>
  2.     <!-- Elasticsearch Java Client -->
  3.     <dependency>
  4.         <groupId>co.elastic.clients</groupId>
  5.         <artifactId>elasticsearch-java</artifactId>
  6.         <version>8.10.0</version>
  7.     </dependency>
  8.    
  9.     <!-- JSON 处理 -->
  10.     <dependency>
  11.         <groupId>com.fasterxml.jackson.core</groupId>
  12.         <artifactId>jackson-databind</artifactId>
  13.         <version>2.15.2</version>
  14.     </dependency>
  15.    
  16.     <!-- Jakarta JSON 处理 -->
  17.     <dependency>
  18.         <groupId>jakarta.json</groupId>
  19.         <artifactId>jakarta.json-api</artifactId>
  20.         <version>2.1.1</version>
  21.     </dependency>
  22. </dependencies>
复制代码
2. 客户端初始化

Elasticsearch Java客户端有三层布局:


  • 低级客户端:处理HTTP请求
  • 传输层:处理序列化/反序列化
  • API客户端:提供类型安全的API
  1. // 创建低级客户端
  2. RestClient restClient = RestClient.builder(
  3.     new HttpHost("localhost", 9200)).build();
  4. // 创建传输层
  5. ElasticsearchTransport transport = new RestClientTransport(
  6.     restClient, new JacksonJsonpMapper());
  7. // 创建API客户端
  8. ElasticsearchClient client = new ElasticsearchClient(transport);
复制代码
3. 底子操纵

创建索引

  1. // 创建索引并设置映射
  2. CreateIndexRequest requestWithMapping = new CreateIndexRequest.Builder()
  3.     .index("products")
  4.     .mappings(m -> m
  5.         .properties("name", p -> p.text(t -> t
  6.             .analyzer("ik_max_word")
  7.             .searchAnalyzer("ik_smart")))
  8.         .properties("price", p -> p.float_())
  9.         .properties("description", p -> p.text(t -> t
  10.             .analyzer("ik_max_word")))
  11.         .properties("createTime", p -> p.date())
  12.     )
  13.     .build();
  14.    
  15. client.indices().create(requestWithMapping);
复制代码
添加文档

  1. // 定义产品实体类
  2. public class Product {
  3.     private String id;
  4.     private String name;
  5.     private float price;
  6.     private String description;
  7.     private Date createTime;
  8.    
  9.     // getters and setters
  10. }
  11. // 添加文档
  12. Product product = new Product();
  13. product.setId("1");
  14. product.setName("iPhone 13");
  15. product.setPrice(5999.00f);
  16. product.setDescription("Apple iPhone 13 128GB");
  17. product.setCreateTime(new Date());
  18. IndexRequest<Product> indexRequest = new IndexRequest.Builder<Product>()
  19.     .index("products")
  20.     .id(product.getId())
  21.     .document(product)
  22.     .build();
  23.    
  24. IndexResponse response = client.index(indexRequest);
复制代码
查询文档

  1. // 根据ID查询
  2. GetRequest getRequest = new GetRequest.Builder()
  3.     .index("products")
  4.     .id("1")
  5.     .build();
  6.    
  7. GetResponse<Product> getResponse = client.get(getRequest, Product.class);
  8. // 条件查询
  9. SearchRequest searchRequest = new SearchRequest.Builder()
  10.     .index("products")
  11.     .query(q -> q
  12.         .match(m -> m
  13.             .field("name")
  14.             .query("iPhone")
  15.         )
  16.     )
  17.     .build();
  18.    
  19. SearchResponse<Product> searchResponse = client.search(searchRequest, Product.class);
复制代码
4. 高级搜索

布尔查询

  1. SearchRequest boolRequest = new SearchRequest.Builder()
  2.     .index("products")
  3.     .query(q -> q
  4.         .bool(b -> b
  5.             .must(m -> m
  6.                 .match(t -> t
  7.                     .field("name")
  8.                     .query("iPhone")
  9.                 )
  10.             )
  11.             .filter(f -> f
  12.                 .range(r -> r
  13.                     .field("price")
  14.                     .gte(JsonData.of(5000))
  15.                     .lte(JsonData.of(10000))
  16.                 )
  17.             )
  18.             .should(s -> s
  19.                 .match(t -> t
  20.                     .field("description")
  21.                     .query("Pro")
  22.                 )
  23.             )
  24.             .minimumShouldMatch("1")
  25.         )
  26.     )
  27.     .build();
复制代码
聚合查询

  1. SearchRequest aggregationRequest = new SearchRequest.Builder()
  2.     .index("products")
  3.     .size(0)  // 不返回文档,只返回聚合结果
  4.     .aggregations("price_stats", a -> a
  5.         .stats(s -> s
  6.             .field("price")
  7.         )
  8.     )
  9.     .build();
复制代码
高亮搜索结果

  1. SearchRequest highlightRequest = new SearchRequest.Builder()
  2.     .index("products")
  3.     .query(q -> q
  4.         .match(m -> m
  5.             .field("description")
  6.             .query("iPhone")
  7.         )
  8.     )
  9.     .highlight(h -> h
  10.         .fields("description", f -> f
  11.             .preTags("<em>")
  12.             .postTags("</em>")
  13.             .numberOfFragments(3)
  14.         )
  15.     )
  16.     .build();
复制代码
5. 批量操纵

批量操纵可以大幅提高性能,减少网络请求次数:
  1. // 准备批量数据
  2. List<Product> products = new ArrayList<>();
  3. for (int i = 1; i <= 100; i++) {
  4.     Product product = new Product();
  5.     product.setId(String.valueOf(i));
  6.     product.setName("Product " + i);
  7.     product.setPrice(1000 + i * 10.0f);
  8.     product.setDescription("Description for product " + i);
  9.     product.setCreateTime(new Date());
  10.     products.add(product);
  11. }
  12. // 批量索引
  13. BulkRequest.Builder br = new BulkRequest.Builder();
  14. for (Product product : products) {
  15.     br.operations(op -> op
  16.         .index(idx -> idx
  17.             .index("products")
  18.             .id(product.getId())
  19.             .document(product)
  20.         )
  21.     );
  22. }
  23. BulkRequest request = br.build();
  24. BulkResponse response = client.bulk(request);
复制代码
6. 最佳实践

客户端配置优化

  1. RestClientBuilder builder = RestClient.builder(
  2.     new HttpHost("localhost", 9200))
  3.     .setRequestConfigCallback(requestConfigBuilder -> {
  4.         // 设置连接超时时间(默认1秒)
  5.         requestConfigBuilder.setConnectTimeout(5000);
  6.         // 设置套接字超时时间(默认30秒)
  7.         requestConfigBuilder.setSocketTimeout(60000);
  8.         return requestConfigBuilder;
  9.     })
  10.     .setHttpClientConfigCallback(httpClientBuilder -> {
  11.         // 设置最大连接数
  12.         httpClientBuilder.setMaxConnPerRoute(50);
  13.         httpClientBuilder.setMaxConnTotal(200);
  14.         return httpClientBuilder;
  15.     });
复制代码
非常处理

  1. try {
  2.     SearchRequest searchRequest = new SearchRequest.Builder()
  3.         .index("non_existent_index")
  4.         .query(q -> q.matchAll(m -> m))
  5.         .build();
  6.         
  7.     SearchResponse<Product> response = client.search(searchRequest, Product.class);
  8. } catch (ElasticsearchException e) {
  9.     if (e.status() == 404) {
  10.         System.err.println("索引不存在: " + e.getMessage());
  11.     } else if (e.status() == 400) {
  12.         System.err.println("请求错误: " + e.getMessage());
  13.     }
  14. } catch (IOException e) {
  15.     System.err.println("IO 异常: " + e.getMessage());
  16. }
复制代码
封装服务类

  1. @Service
  2. public class ElasticsearchService<T> {
  3.    
  4.     private final ElasticsearchClient client;
  5.     private final Class<T> entityClass;
  6.     private final String indexName;
  7.    
  8.     // 构造函数、保存、查询、删除等方法...
  9.    
  10.     // 条件查询
  11.     public List<T> search(Query query, int from, int size) throws IOException {
  12.         SearchRequest request = new SearchRequest.Builder()
  13.             .index(indexName)
  14.             .query(query)
  15.             .from(from)
  16.             .size(size)
  17.             .build();
  18.             
  19.         SearchResponse<T> response = client.search(request, entityClass);
  20.         return response.hits().hits().stream()
  21.             .map(Hit::source)
  22.             .collect(Collectors.toList());
  23.     }
  24. }
复制代码
7. Spring Data Elasticsearch

如果你利用Spring Boot,可以通过Spring Data Elasticsearch更简单地集成:
  1. <dependency>
  2.     <groupId>org.springframework.boot</groupId>
  3.     <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
  4. </dependency>
复制代码
实体类定义:
  1. @Document(indexName = "products")
  2. public class Product {
  3.    
  4.     @Id
  5.     private String id;
  6.    
  7.     @Field(type = FieldType.Text, analyzer = "ik_max_word")
  8.     private String name;
  9.    
  10.     @Field(type = FieldType.Float)
  11.     private float price;
  12.    
  13.     // 其他字段...
  14. }
复制代码
Repository接口:
  1. public interface ProductRepository extends ElasticsearchRepository<Product, String> {
  2.    
  3.     // 根据名称查询
  4.     List<Product> findByName(String name);
  5.    
  6.     // 根据价格范围查询
  7.     List<Product> findByPriceBetween(float minPrice, float maxPrice);
  8.    
  9.     // 自定义查询
  10.     @Query("{"bool": {"must": [{"match": {"name": "?0"}}]}}")
  11.     Page<Product> findByNameCustomQuery(String name, Pageable pageable);
  12. }
复制代码
总结

本指南详细介绍了Java与Elasticsearch的集成方法,包括:

  • 环境配置:添加依赖和初始化客户端
  • 底子操纵:索引创建、文档的增编削查
  • 高级搜索:布尔查询、聚合、高亮等
  • 批量操纵:提高性能的批量处理
  • 最佳实践:客户端优化、非常处理、服务封装
  • Spring集成:利用Spring Data简化操纵
通过这些内容,你应该可以或许在Java应用中有用地利用Elasticsearch,实现高性能的搜索和数据分析功能。
如果你有特定的利用场景或问题,可以参考官方文档或社区资源获取更多信息。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

钜形不锈钢水箱

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表