Elasticsearch RestclientApi基础用法
索引
初始化
添加依赖
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
</dependency>
创建链接
package com.hmall.item.es;
import org.apache.http.HttpHost;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.common.xcontent.XContentType;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import static org.junit.jupiter.api.Assertions.*;
/**
* @ Author qwh
* @ Date 2024/6/19 8:51
*/
class itemApplicationTest {
private RestHighLevelClient client;
//创建链接
@BeforeEach
void setup(){
this.client = new RestHighLevelClient(RestClient.builder(
HttpHost.create("http://192.168.70.145:9200")
));
}
//测试链接
@Test
void testConnect(){
System.out.println(client);
}
//关闭链接
@AfterEach
void destroy() throws IOException {
this.client.close();
}
}
创建索引库
@Test
void CreateIndex() throws IOException {
//1
CreateIndexRequest request = new CreateIndexRequest("items");
//2
request.source(MAPPING_TEMPLATE, XContentType.JSON);
//3
client.indices().create(request, RequestOptions.DEFAULT);
}
static final String MAPPING_TEMPLATE = "{\n" +
" \"mappings\": {\n" +
" \"properties\": {\n" +
" \"id\": {\n" +
" \"type\": \"keyword\"\n" +
" },\n" +
" \"name\":{\n" +
" \"type\": \"text\",\n" +
" \"analyzer\": \"ik_max_word\"\n" +
" },\n" +
" \"price\":{\n" +
" \"type\": \"integer\"\n" +
" },\n" +
" \"stock\":{\n" +
" \"type\": \"integer\"\n" +
" },\n" +
" \"image\":{\n" +
" \"type\": \"keyword\",\n" +
" \"index\": false\n" +
" },\n" +
" \"category\":{\n" +
" \"type\": \"keyword\"\n" +
" },\n" +
" \"brand\":{\n" +
" \"type\": \"keyword\"\n" +
" },\n" +
" \"sold\":{\n" +
" \"type\": \"integer\"\n" +
" },\n" +
" \"commentCount\":{\n" +
" \"type\": \"integer\"\n" +
" },\n" +
" \"isAD\":{\n" +
" \"type\": \"boolean\"\n" +
" },\n" +
" \"updateTime\":{\n" +
" \"type\": \"date\"\n" +
" }\n" +
" }\n" +
" }\n" +
"}";
删除索引库
//删除索引库
@Test
void DeleteIndex() throws IOException {
//创建请求对象
DeleteIndexRequest items = new DeleteIndexRequest("items");
//发送请求
client.indices().delete(items,RequestOptions.DEFAULT);
}
判断索引库是否存在
@Test
void GetIndex() throws IOException {
//发送请求
GetIndexRequest items = new GetIndexRequest("items");
boolean exists = client.indices().exists(items, RequestOptions.DEFAULT);
System.out.println(exists ? "索引库已经存在" : "索引不存在");
}
文档
新增文档
- 实体类
package com.hmall.item.domain.po;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.time.LocalDateTime;
@Data
@ApiModel(description = "索引库实体")
public class ItemDoc{
@ApiModelProperty("商品id")
private String id;
@ApiModelProperty("商品名称")
private String name;
@ApiModelProperty("价格(分)")
private Integer price;
@ApiModelProperty("商品图片")
private String image;
@ApiModelProperty("类目名称")
private String category;
@ApiModelProperty("品牌名称")
private String brand;
@ApiModelProperty("销量")
private Integer sold;
@ApiModelProperty("评论数")
private Integer commentCount;
@ApiModelProperty("是否是推广广告,true/false")
private Boolean isAD;
@ApiModelProperty("更新时间")
private LocalDateTime updateTime;
}
- api语法
POST /{索引库名}/_doc/1
{
"name": "Jack",
"age": 21
}
- java
- 1)创建Request对象,这里是IndexRequest,因为添加文档就是创建倒排索引的过程
- 2)准备请求参数,本例中就是Json文档
- 3)发送请求
package com.hmall.item.es;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hmall.common.utils.CollUtils;
import com.hmall.item.domain.po.Item;
import com.hmall.item.domain.po.ItemDoc;
import com.hmall.item.service.IItemService;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpHost;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.io.IOException;
import java.util.List;
/**
* @ Author qwh
* @ Date 2024/6/19 9:29
*/
@Slf4j
@SpringBootTest(properties = "spring.profiles.active=local")
public class itemDocTest {
private RestHighLevelClient client;
@Autowired
private IItemService iItemService;
@BeforeEach
void setup(){
client = new RestHighLevelClient(RestClient.builder(
HttpHost.create("http://192.168.70.145:9200")
));
}
@Test //添加文档
void addDocument() throws IOException {
//根据id查询item 添加到es
Item item = iItemService.getById(100002644680L);
//转换为文档类型
ItemDoc itemDoc = BeanUtil.copyProperties(item, ItemDoc.class);
//将文档类型转换为json
String doc = JSONUtil.toJsonStr(itemDoc);
System.out.println(doc.toString());
// 1.准备Request对象
IndexRequest request = new IndexRequest("items").id(itemDoc.getId());
// 2.准备Json文档
request.source(doc, XContentType.JSON);
// 3.发送请求
client.index(request, RequestOptions.DEFAULT);
}
@AfterEach
void destroy() throws IOException {
this.client.close();
}
}
查询文档
- api
GET /{索引库名}/_doc/{id}
- java
- 1)准备Request对象。这次是查询,所以是GetRequest
- 2)发送请求,得到结果。因为是查询,这里调用client.get()方法
- 3)解析结果,就是对JSON做反序列化
@Test
void GetDocument() throws IOException {
GetRequest request = new GetRequest("items").id("100002644680");
//发送请求
GetResponse response = client.get(request, RequestOptions.DEFAULT);
//获取相应结果
String json = response.getSourceAsString();
ItemDoc itemDoc = JSONUtil.toBean(json, ItemDoc.class);
System.out.println("itemDoc"+itemDoc);
}
删除文档
- api
DELETE /{索引库}/_doc/{id}
- java
- 1)准备Request对象,因为是删除,这次是DeleteRequest对象。要指定索引库名和id
- 2)
准备参数,无参,直接省略 - 3)发送请求。因为是删除,所以是client.delete()方法
@Test
void deleteDocument() throws IOException {
//准备request 参数 索引库名 文档id
DeleteRequest request = new DeleteRequest("items", "100002644680");
client.delete(request,RequestOptions.DEFAULT);
}
修改文档
- 全量修改:本质是先根据id删除,再新增
- 局部修改:修改文档中的指定字段值
- api 局部修改
POST /{索引库名}/_update/{id}
{
"doc": {
"字段名": "字段值",
"字段名": "字段值"
}
}
- java
- 1)准备Request对象。这次是修改,所以是UpdateRequest
- 2)准备参数。也就是JSON文档,里面包含要修改的字段
- 3)更新文档。这里调用client.update()方法
//修改文档
@Test
void updateDocument() throws IOException {
//request
UpdateRequest request = new UpdateRequest("items", "100002644680");
//修改内容
request.doc("price",99999,"commentCount",1);
//发送请求
client.update(request,RequestOptions.DEFAULT);
}
批量导入
- java
- 创建Request,但这次用的是BulkRequest
- 准备请求参数
- 发送请求,这次要用到client.bulk()方法
//批量导入
@Test
void loadItemDocs() throws IOException {
//分页查询
int curPage = 1;
int size = 1000;
while (true){
Page<Item> page = iItemService.lambdaQuery().eq(Item::getStatus, 1).page(new Page<>(curPage, size));
//f非空校验
List<Item> items = page.getRecords();
if (CollUtils.isEmpty(items)) {
return;
}
log.info("加载第{}页数据共{}条",curPage,items.size());
//创建request
BulkRequest request = new BulkRequest("items");
//准备参数
for (Item item : items) {
ItemDoc itemDoc = BeanUtil.copyProperties(item, ItemDoc.class);
request.add(new IndexRequest().id(itemDoc.getId()).source(JSONUtil.toJsonStr(itemDoc),XContentType.JSON));
}
//发送请求
client.bulk(request,RequestOptions.DEFAULT);
curPage++;
}
}
文档操作的基本步骤:
- 初始化RestHighLevelClient
- 创建XxxRequest。
- XXX是Index、Get、Update、Delete、Bulk
- 准备参数(Index、Update、Bulk时需要)
- 发送请求。
- 调用RestHighLevelClient#.xxx()方法,xxx是index、get、update、delete、bulk
- 解析结果(Get时需要)