Java ES索引案例如何创建删除

wen java案例 31

本文目录导读:

Java ES索引案例如何创建删除

  1. 前置准备:依赖与客户端连接
  2. 案例一:使用 Spring Data Elasticsearch
  3. 案例二:使用官方 Java Client (8.x)
  4. 总结与对比

在 Java 中操作 Elasticsearch 索引,通常有两种主流方式:

  1. Spring Data Elasticsearch:推荐用于 Spring Boot 项目,更符合 Spring 的编程习惯。
  2. Elasticsearch Java Client (8.x):官方原生客户端,功能全面,性能好。

我将分别展示这两种方式创建删除索引的案例,以 Elasticsearch 8.x 版本为例。


前置准备:依赖与客户端连接

无论哪种方式,都需要先连接 ES 服务器。

Maven 依赖

<!-- 1. Spring Data Elasticsearch -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
    <version>3.2.0</version> 
</dependency>
<!-- 2. 官方 Java Client -->
<dependency>
    <groupId>co.elastic.clients</groupId>
    <artifactId>elasticsearch-java</artifactId>
    <version>8.12.0</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.17.0</version>
</dependency>

使用 Spring Data Elasticsearch

这种方式通过@Document注解和ElasticsearchOperations模板类操作索引。

定义实体类(同时也是索引映射)

import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;
// 定义索引名为 "user_index",分片数1,副本数0
@Document(indexName = "user_index", shards = 1, replicas = 0)
public class UserDocument {
    @Id
    private String id;
    @Field(type = FieldType.Text, analyzer = "ik_smart") // 指定分词器
    private String name;
    @Field(type = FieldType.Integer)
    private Integer age;
    @Field(type = FieldType.Keyword)
    private String email;
    // Getters & Setters
    public String getId() { return id; }
    public void setId(String id) { this.id = id; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public Integer getAge() { return age; }
    public void setAge(Integer age) { this.age = age; }
    public String getEmail() { return email; }
    public void setEmail(String email) { this.email = email; }
}

创建和删除索引的实现

import org.elasticsearch.client.RestHighLevelClient; // 注意:Spring Data 3.x 底层已使用新客户端
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
import org.springframework.data.elasticsearch.core.IndexOperations;
import org.springframework.stereotype.Service;
@Service
public class IndexService {
    @Autowired
    private ElasticsearchOperations elasticsearchOperations;
    /**
     * 创建索引(基于@Document注解的配置)
     * 如果索引已存在,Spring Data 默认会忽略或报错,这里处理为安全创建。
     */
    public boolean createIndex() {
        // 获取针对 UserDocument 类的索引操作对象
        IndexOperations indexOps = elasticsearchOperations.indexOps(UserDocument.class);
        // 检查索引是否存在
        if (!indexOps.exists()) {
            // 创建索引并应用映射
            boolean created = indexOps.create();
            System.out.println("索引创建成功: " + created);
            return created;
        } else {
            System.out.println("索引已存在,跳过创建");
            return true; // 返回 true 表示索引可用
        }
    }
    /**
     * 删除索引
     */
    public boolean deleteIndex() {
        IndexOperations indexOps = elasticsearchOperations.indexOps(UserDocument.class);
        boolean deleted = indexOps.delete();
        System.out.println("索引删除成功: " + deleted);
        return deleted;
    }
}

调用示例

// 在 Controller 或测试类中注入 IndexService
@Autowired
private IndexService indexService;
// 创建
indexService.createIndex();
// 删除
indexService.deleteIndex();

使用官方 Java Client (8.x)

这种方式更底层,需要手动构建 JSON 格式的映射(Mapping)和设置(Settings)。

创建索引

import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch.indices.CreateIndexRequest;
import co.elastic.clients.elasticsearch.indices.CreateIndexResponse;
import co.elastic.clients.elasticsearch.indices.DeleteIndexRequest;
import co.elastic.clients.elasticsearch.indices.DeleteIndexResponse;
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.Header;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.elasticsearch.client.RestClient;
import java.io.IOException;
public class IndexManager {
    private ElasticsearchClient client;
    // 构建客户端连接
    public IndexManager() {
        // 1. 创建 RestClient
        BasicCredentialsProvider credsProv = new BasicCredentialsProvider();
        credsProv.setCredentials(
            AuthScope.ANY,
            new UsernamePasswordCredentials("elastic", "your_password")
        );
        RestClient restClient = RestClient.builder(new HttpHost("localhost", 9200, "https"))
                .setHttpClientConfigCallback(httpClientBuilder -> 
                    httpClientBuilder.setDefaultCredentialsProvider(credsProv)
                )
                .build();
        // 2. 创建 Transport
        ElasticsearchTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper());
        // 3. 创建 Client
        this.client = new ElasticsearchClient(transport);
    }
    /**
     * 创建索引(包含 Mapping 和 Settings)
     */
    public boolean createIndexWithMapping() throws IOException {
        String indexName = "product_index";
        // 检查索引是否存在
        boolean exists = client.indices().exists(e -> e.index(indexName)).value();
        if (exists) {
            System.out.println("索引 [" + indexName + "] 已存在");
            return true;
        }
        // 创建索引请求
        CreateIndexRequest request = new CreateIndexRequest.Builder()
                .index(indexName)
                .settings(s -> s
                    .numberOfShards("3")
                    .numberOfReplicas("1")
                )
                .mappings(m -> m
                    .properties("name", p -> p.text(t -> t.analyzer("standard"))) // 标准分词
                    .properties("price", p -> p.double_(d -> d))
                    .properties("tags", p -> p.keyword(k -> k))
                    .properties("createdAt", p -> p.date(d -> d.format("yyyy-MM-dd HH:mm:ss")))
                )
                .build();
        // 执行创建
        CreateIndexResponse response = client.indices().create(request);
        boolean acknowledged = response.acknowledged();
        System.out.println("索引 [" + indexName + "] 创建结果: " + acknowledged);
        return acknowledged;
    }
    /**
     * 删除索引
     */
    public boolean deleteIndex() throws IOException {
        String indexName = "product_index";
        // 检查是否存在
        boolean exists = client.indices().exists(e -> e.index(indexName)).value();
        if (!exists) {
            System.out.println("索引 [" + indexName + "] 不存在,无法删除");
            return false;
        }
        // 删除索引
        DeleteIndexResponse response = client.indices().delete(d -> d.index(indexName));
        boolean acknowledged = response.acknowledged();
        System.out.println("索引 [" + indexName + "] 删除结果: " + acknowledged);
        return acknowledged;
    }
    // 关闭连接
    public void close() throws IOException {
        if (client != null) {
            client._transport().close();
        }
    }
}

调用示例

IndexManager manager = new IndexManager();
try {
    // 创建
    manager.createIndexWithMapping();
    // 删除
    manager.deleteIndex();
} catch (IOException e) {
    e.printStackTrace();
} finally {
    manager.close();
}

总结与对比

特性 Spring Data Elasticsearch 官方 Java Client (8.x)
代码简洁性 ⭐⭐⭐⭐⭐ (注解驱动) ⭐⭐⭐ (需要手写映射)
灵活性 ⭐⭐⭐ (依赖注解约定) ⭐⭐⭐⭐⭐ (完全控制)
推荐场景 Spring Boot 项目,标准 CRUD 需要精细控制 Mapping/Settings
Mapping 定义 实体类注解自动生成 手动构建 Builder 或 JSON

建议

  • 如果是 Spring Boot 项目,优先选择 Spring Data Elasticsearch,你只需定义好实体类(如@Document)和 Repository 接口,索引操作由框架自动处理。
  • 如果你需要精细控制索引的 Mapping、Settings(如指定自定义分词器、复杂的字段类型),或者你的项目不是基于 Spring,推荐使用 官方 Java Client

抱歉,评论功能暂时关闭!