在java项目中项目里集成ES

1. 引入依赖(Maven)

需保证客户端版本与 ES 服务器版本一致:

xml 复制代码
<dependency>
    <groupId>co.elastic.clients</groupId>
    <artifactId>elasticsearch-java</artifactId>
    <version>8.10.0</version> <!-- 与ES服务器版本一致 -->
</dependency>
<!-- 依赖Jackson处理JSON -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.14.2</version>
</dependency>

2. 配置 ES 连接

创建客户端实例,配置 ES 集群地址、认证信息等:

java 复制代码
import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
import co.elastic.clients.transport.ElasticsearchTransport;
import co.elastic.clients.transport.rest_client.RestClientTransport;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;

public class ESClientConfig {
    public static ElasticsearchClient getClient() {
        // 1. 创建REST客户端(配置ES集群地址,可多个)
        RestClient restClient = RestClient.builder(
                new HttpHost("localhost", 9200, "http"),  // 节点1
                new HttpHost("localhost", 9201, "http")   // 节点2(集群时配置)
        ).build();

        // 2. 创建传输层(关联REST客户端和JSON处理器)
        ElasticsearchTransport transport = new RestClientTransport(
                restClient, new JacksonJsonpMapper()
        );

        // 3. 创建ES客户端(核心操作入口)
        return new ElasticsearchClient(transport);
    }
}

如果 ES 开启了安全认证(如账号密码),需在 RestClient 中添加认证拦截器:

java 复制代码
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;

// 在RestClient.builder()前添加认证
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY,
        new UsernamePasswordCredentials("elastic", "your-password"));

RestClient restClient = RestClient.builder(...)
        .setHttpClientConfigCallback(httpClientBuilder -> 
                httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider))
        .build();

3. 核心功能实现

(1)索引管理(创建 / 删除索引)
java 复制代码
import co.elastic.clients.elasticsearch.indices.CreateIndexRequest;
import co.elastic.clients.elasticsearch.indices.ElasticsearchIndicesClient;

public class IndexManager {
    private final ElasticsearchClient client = ESClientConfig.getClient();
    private final ElasticsearchIndicesClient indicesClient = client.indices();

    // 创建索引(含映射配置)
    public void createIndex(String indexName) throws Exception {
        // 定义映射(以"product"索引为例:id、name、price、createTime字段)
        String mapping = "{\n" +
                "  "properties": {\n" +
                "    "id": { "type": "keyword" },\n" +
                "    "name": { "type": "text", "analyzer": "ik_max_word" },\n" +
                "    "price": { "type": "double" },\n" +
                "    "createTime": { "type": "date", "format": "yyyy-MM-dd HH:mm:ss" }\n" +
                "  }\n" +
                "}";

        CreateIndexRequest request = CreateIndexRequest.of(b -> b
                .index(indexName)
                .mappings(m -> m.withJson(new StringReader(mapping)))
        );

        indicesClient.create(request);
        System.out.println("索引创建成功:" + indexName);
    }

    // 删除索引
    public void deleteIndex(String indexName) throws Exception {
        indicesClient.delete(d -> d.index(indexName));
        System.out.println("索引删除成功:" + indexName);
    }
}
(2)文档操作(增删改查)

假设存在实体类Product

java 复制代码
import com.fasterxml.jackson.annotation.JsonFormat;
import java.util.Date;

public class Product {
    private String id;
    private String name;
    private Double price;
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private Date createTime;

    //  getter/setter 省略
}

文档操作示例:

java 复制代码
import co.elastic.clients.elasticsearch.core.*;
import co.elastic.clients.elasticsearch.core.search.Hit;

public class DocumentService {
    private final ElasticsearchClient client = ESClientConfig.getClient();
    private static final String INDEX_NAME = "product";

    // 新增文档(自动生成ID)
    public void addDocument(Product product) throws Exception {
        IndexRequest<Product> request = IndexRequest.of(b -> b
                .index(INDEX_NAME)
                .document(product)
        );
        IndexResponse response = client.index(request);
        System.out.println("新增文档ID:" + response.id());
    }

    // 根据ID查询文档
    public Product getDocumentById(String id) throws Exception {
        GetRequest request = GetRequest.of(b -> b.index(INDEX_NAME).id(id));
        GetResponse<Product> response = client.get(request, Product.class);
        return response.found() ? response.source() : null;
    }

    // 更新文档(全量更新)
    public void updateDocument(String id, Product product) throws Exception {
        UpdateRequest<Product, Product> request = UpdateRequest.of(b -> b
                .index(INDEX_NAME)
                .id(id)
                .doc(product)
        );
        client.update(request, Product.class);
    }

    // 删除文档
    public void deleteDocument(String id) throws Exception {
        DeleteRequest request = DeleteRequest.of(b -> b.index(INDEX_NAME).id(id));
        client.delete(request);
    }
}
(3)查询操作(全文检索、条件过滤等)
java 复制代码
import co.elastic.clients.elasticsearch.core.SearchRequest;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.elasticsearch.core.search.Hit;
import co.elastic.clients.elasticsearch.query_dsl.QueryBuilders;

import java.util.List;
import java.util.stream.Collectors;

public class SearchService {
    private final ElasticsearchClient client = ESClientConfig.getClient();
    private static final String INDEX_NAME = "product";

    // 全文检索(搜索name中包含"手机"的商品)
    public List<Product> searchByKeyword(String keyword) throws Exception {
        SearchRequest request = SearchRequest.of(b -> b
                .index(INDEX_NAME)
                .query(q -> q
                        .match(m -> m
                                .field("name")  // 检索字段
                                .query(keyword) // 检索关键词
                        )
                )
        );

        SearchResponse<Product> response = client.search(request, Product.class);
        return response.hits().hits().stream()
                .map(Hit::source)
                .collect(Collectors.toList());
    }

    // 条件过滤(价格大于1000的商品,分页查询)
    public List<Product> searchByPrice(Double minPrice, int page, int size) throws Exception {
        SearchRequest request = SearchRequest.of(b -> b
                .index(INDEX_NAME)
                .query(q -> q
                        .range(r -> r
                                .field("price")
                                .gt(minPrice)  // 价格>minPrice
                        )
                )
                .from((page - 1) * size)  // 分页起始位置
                .size(size)               // 每页条数
        );

        SearchResponse<Product> response = client.search(request, Product.class);
        return response.hits().hits().stream()
                .map(Hit::source)
                .collect(Collectors.toList());
    }
}

三、Spring Boot 项目中的简化实现(Spring Data Elasticsearch)

如果项目基于 Spring Boot,可使用spring-data-elasticsearch简化配置:

  1. 引入依赖:
xml 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
  1. 配置 ES 地址(application.yml):
yaml 复制代码
spring:
  elasticsearch:
    uris: http://localhost:9200,http://localhost:9201
    username: elastic
    password: your-password
  1. 定义 Repository 接口(类似 JPA):
java 复制代码
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import java.util.List;

// Product实体类需添加@Document注解指定索引
@Document(indexName = "product")
public class Product { ... }

// 继承ElasticsearchRepository,自动实现CRUD方法
public interface ProductRepository extends ElasticsearchRepository<Product, String> {
    // 自定义查询(根据name模糊查询)
    List<Product> findByNameContaining(String keyword);
    
    // 价格范围查询
    List<Product> findByPriceGreaterThan(Double minPrice);
}
  1. 服务层直接注入使用:
java 复制代码
@Service
public class ProductService {
    @Autowired
    private ProductRepository productRepository;

    public void addProduct(Product product) {
        productRepository.save(product);
    }

    public List<Product> searchByName(String keyword) {
        return productRepository.findByNameContaining(keyword);
    }
}
相关推荐
Python私教2 小时前
Django全栈班v1.04 Python基础语法 20250912 下午
后端·python·django
爱读源码的大都督3 小时前
为什么Spring 6中要把synchronized替换为ReentrantLock?
java·后端·架构
这里有鱼汤3 小时前
发现一个高性能回测框架,Python + Rust,比 backtrader 快 250 倍?小团队必备!
后端·python
程序员爱钓鱼3 小时前
Go语言实战案例 — 项目实战篇:图书管理系统(文件存储)
后端·google·go
元闰子3 小时前
OLTP上云,哪种架构最划算?·VLDB'25
数据库·后端·云原生
IT_陈寒3 小时前
Vite 5.0重磅升级:8个性能优化秘诀让你的构建速度飙升200%!🚀
前端·人工智能·后端
hui函数4 小时前
scrapy框架-day02
后端·爬虫·python·scrapy
Moshow郑锴4 小时前
SpringBootCodeGenerator使用JSqlParser解析DDL CREATE SQL 语句
spring boot·后端·sql
小沈同学呀10 小时前
创建一个Spring Boot Starter风格的Basic认证SDK
java·spring boot·后端