【用 Java API Client 操作 Elasticsearch】
🚀 一篇搞懂:用 Java API Client 操作 Elasticsearch(超详细 + 通俗易懂)
大家好,这篇文章我们来从0开始讲清楚:如何用Java API Client操作 Elasticsearch。
一、什么是 Java API Client?
在 Elasticsearch 8.x 之后,官方推荐使用:
👉Java API Client(co.elastic.clients)
替代旧的:
- RestHighLevelClient(已经被废弃)
它的特点是:
- ✅ 类型安全(强类型,不再是字符串拼JSON)
- ✅ API更现代
- ✅ 和ES版本强绑定
二、环境准备
1️⃣ Maven 依赖
<dependencies><!-- Elasticsearch Java API Client --><dependency><groupId>co.elastic.clients</groupId><artifactId>elasticsearch-java</artifactId><version>8.12.0</version></dependency><!-- 低级客户端 --><dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-client</artifactId><version>8.12.0</version></dependency><!-- JSON 处理 --><dependency><groupId>jakarta.json</groupId><artifactId>jakarta.json-api</artifactId><version>2.0.1</version></dependency></dependencies>2️⃣ 创建客户端
这是所有操作的基础,必须掌握。
RestClientrestClient=RestClient.builder(newHttpHost("localhost",9200)).build();ElasticsearchTransporttransport=newRestClientTransport(restClient,newJacksonJsonpMapper());ElasticsearchClientclient=newElasticsearchClient(transport);👉 一句话理解:
- RestClient:负责HTTP通信
- Transport:负责数据转换
- Client:我们真正用的API
三、索引操作(Index)
1️⃣ 创建索引
client.indices().create(c->c.index("user_index"));2️⃣ 删除索引
client.indices().delete(d->d.index("user_index"));3️⃣ 判断索引是否存在
Booleanexists=client.indices().exists(e->e.index("user_index")).value();System.out.println(exists);四、文档操作(CRUD)
我们定义一个实体类:
classUser{publicStringname;publicintage;}1️⃣ 插入文档(Create)
Useruser=newUser();user.name="张三";user.age=20;client.index(i->i.index("user_index").id("1").document(user));2️⃣ 查询文档(Read)
GetResponse<User>response=client.get(g->g.index("user_index").id("1"),User.class);Useruser=response.source();System.out.println(user.name);3️⃣ 更新文档(Update)
client.update(u->u.index("user_index").id("1").doc(newUser(){{age=25;}}),User.class);4️⃣ 删除文档(Delete)
client.delete(d->d.index("user_index").id("1"));五、查询操作(重点🔥)
1️⃣ match 查询(全文检索)
SearchResponse<User>response=client.search(s->s.index("user_index").query(q->q.match(m->m.field("name").query("张三"))),User.class);2️⃣ term 查询(精确匹配)
.query(q->q.term(t->t.field("age").value(25)))3️⃣ 范围查询(range)
.query(q->q.range(r->r.field("age").gte(JsonData.of(20)).lte(JsonData.of(30))))4️⃣ bool 查询(组合查询)
.query(q->q.bool(b->b.must(m->m.match(mm->mm.field("name").query("张三"))).filter(f->f.range(r->r.field("age").gte(JsonData.of(20))))))👉 理解:
- must:必须满足(参与评分)
- filter:过滤(不参与评分,更快)
5️⃣ 解析结果
for(Hit<User>hit:response.hits().hits()){Useruser=hit.source();System.out.println(user.name+" "+user.age);}六、分页查询
SearchResponse<User>response=client.search(s->s.index("user_index").from(0)// 起始位置.size(10)// 每页数量.query(q->q.match(m->m.field("name").query("张三"))),User.class);七、排序
.sort(s->s.field(f->f.field("age").order(SortOrder.Desc)))八、一个完整小案例(推荐直接跑🔥)
publicstaticvoidmain(String[]args)throwsException{ElasticsearchClientclient=createClient();// 1. 创建索引client.indices().create(c->c.index("user_index"));// 2. 插入数据Useruser=newUser();user.name="李四";user.age=30;client.index(i->i.index("user_index").id("1").document(user));// 3. 查询SearchResponse<User>response=client.search(s->s.index("user_index").query(q->q.match(m->m.field("name").query("李四"))),User.class);// 4. 输出for(Hit<User>hit:response.hits().hits()){System.out.println(hit.source().name);}}九、常见坑(一定要看⚠️)
❌ 1. 版本不一致
- Java Client 和 ES 服务端版本必须接近
❌ 2. 字段类型问题
- text → 不能 term 查询
- keyword → 才能精确匹配
❌ 3. JSON 转换问题
- 推荐使用 JacksonJsonpMapper
❌ 4. 中文查询问题
- 需要分词器(ik分词器等)
十、总结
一句话总结:
👉 Java API Client =更安全、更优雅的ES操作方式
