本文目录导读:

在 Java 中操作 Elasticsearch 索引,通常有两种主流方式:
- Spring Data Elasticsearch:推荐用于 Spring Boot 项目,更符合 Spring 的编程习惯。
- 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。
版权声明:足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播