ES官方提供了各种不同语言的客户端,用来操作ES。这些客户端的本质就是组装DSL语句,通过http请求发送给ES。
官方文档地址:https://www.elastic.co/guide/en/elasticsearch/client/java-rest/7.12/java-rest-high.html
其中的Java Rest Client包括两种:
添加配置文件:
创建索引库,关键是要考虑映射,信息包括:字段名、数据类型、是否参与搜索、是否分词、是否分词
PUT /hotel
{
"mappings": {
"properties": {
"id":{
"type": "keyword"
},
"name":{
"type": "text",
"analyzer": "ik_max_word",
"copy_to": "all"
},
"address":{
"type": "keyword",
"index": false
},
"price":{
"type": "integer"
},
"score":{
"type": "integer"
},
"brand":{
"type": "keyword",
"copy_to": "all"
},
"city":{
"type": "keyword",
"copy_to": "all"
},
"startName":{
"type": "keyword",
"copy_to": "all"
},
"business":{
"type": "keyword"
},
"location":{
"type": "geo_point"
},
"pic":{
"type": "keyword",
"index": false
},
"all":{
"type": "text",
"analyzer": "ik_max_word"
}
}
}
}
几个特殊字段说明:
将当前字段拷贝到指定字段中
"all":{
"type": "text",
"analyzer": "ik_max_word"
},
"brand": {
"type": "keywod",
"copy_to": "all"
}
索引库操作的基本步骤:
RestHighLevelClient
XxxIndexRequest
。XXX是Get、Create、DeleteRestHighLevelClient.indices().xxx()
方法,xxx是exists、create、delete@SpringBootTest
public class HotelDocumentTest {
private RestHighLevelClient client;
@BeforeEach
public void init() {
client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("192.168.248.128", 9200, "http")));
}
@AfterEach
void closeClient() throws IOException {
client.close();
}
}
索引库,在kibana中创建
@Test
void testExistsHotelIndex() throws IOException {
// 1.创建Request对象
GetIndexRequest request = new GetIndexRequest("hotel");
// 2.发送请求
boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
// 3.输出
System.err.println(exists ? "索引库已经存在!" : "索引库不存在!");
}
@Test
void testDeleteHotelIndex() throws IOException {
// 1.创建Request对象
DeleteIndexRequest request = new DeleteIndexRequest("hotel");
// 2.发送请求
client.indices().delete(request, RequestOptions.DEFAULT);
}
@Test
void createHotelIndex() throws IOException {
// 1.创建Request对象
CreateIndexRequest request = new CreateIndexRequest("hotel");
// 2.准备请求的参数:DSL语句
request.source(HotelConstants.MAPPING_TEMPLATE, XContentType.JSON);
// 3.发送请求
client.indices().create(request, RequestOptions.DEFAULT);
}
@SpringBootTest
public class HotelDocumentTest {
@Autowired
private HotelMapper hotelMapper;
private RestHighLevelClient client;
@BeforeEach
public void init() {
client = new RestHighLevelClient(
RestClient.builder(
new HttpHost("192.168.136.134", 9200, "http")));
}
@AfterEach
void closeClient() throws IOException {
client.close();
}
}
MySQL:
@Data
@TableName("tb_hotel")
public class Hotel {
@TableId(type = IdType.INPUT)
private Long id;
private String name;
private String address;
private Integer price;
private Integer score;
private String brand;
private String city;
private String starName;
private String business;
private String longitude;
private String latitude;
private String pic;
}
ES:
@Data
@NoArgsConstructor
public class HotelDoc {
private Long id;
private String name;
private String address;
private Integer price;
private Integer score;
private String brand;
private String city;
private String starName;
private String business;
private String location;
private String pic;
private Object distance; // 排序结果显示距离值
private Boolean isAD; // 广告标记
public HotelDoc(Hotel hotel) {
this.id = hotel.getId();
this.name = hotel.getName();
this.address = hotel.getAddress();
this.price = hotel.getPrice();
this.score = hotel.getScore();
this.brand = hotel.getBrand();
this.city = hotel.getCity();
this.starName = hotel.getStarName();
this.business = hotel.getBusiness();
this.location = hotel.getLatitude() + ", " + hotel.getLongitude();
this.pic = hotel.getPic();
}
}
RestHighLevelClient
XxxRequest
。XXX是Index、Get、Update、Delete、BulkRestHighLevelClient..xxx()
方法,xxx是index、get、update、delete、bulk需要注意的是:
//添加文档
@Test
public void testAddDocument() throws Exception {
//1 准备文档数据
// 1-1 根据id查询酒店数据
Hotel hotel = hotelMapper.selectById(61083L);
// 1-2 转为文档实体类型
HotelDoc hotelDoc = new HotelDoc(hotel);
// 1-3 将hotelDoc转为json
String json = JSON.toJSONString(hotelDoc);
//2 创建request
IndexRequest request = new IndexRequest("hotel").id(hotelDoc.getId().toString());
request.source(json, XContentType.JSON);
//3 发送请求
client.index(request, RequestOptions.DEFAULT);
}
查询结果是一个JSON,其中文档放在一个_source
属性中,因此解析就是拿到_source
,反序列化为Java对象即可
//根据id查询文档
@Test
public void testGetDocumentById()throws Exception{
// 1.创建request
GetRequest request = new GetRequest("hotel", "61083");
// 2.发送请求,得到响应
GetResponse response = client.get(request, RequestOptions.DEFAULT);
// 3.解析响应
String json = response.getSourceAsString();
// 4.json转为hotelDoc
HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
System.out.println(hotelDoc);
}
//根据id修改指定文档
@Test
public void testUpdateDocument() throws Exception {
// 1.创建request
UpdateRequest request = new UpdateRequest("hotel", "61083");
//2. 设置更新内容
Map<String, Object> map = new HashMap<>();
map.put("price", 339);
map.put("starName", "四钻");
request.doc(map);
// 3.发送请求
client.update(request, RequestOptions.DEFAULT);
}
删除与查询相比,仅仅是请求方式从GET变成DELETE
//删除文档
@Test
void testDeleteDocument() throws IOException {
// 1.创建Request
DeleteRequest request = new DeleteRequest("hotel", "61083");
// 2.发送请求
client.delete(request, RequestOptions.DEFAULT);
}
批量处理BulkRequest,其本质就是将多个普通的CRUD请求组合在一起发送。
其中提供了一个add方法,用来添加其他请求:
可以看到,能添加的请求包括:
因此Bulk中添加了多个IndexRequest,就是批量新增功能了。示例:
//批量操作
@Test
public void testBulkRequest() throws Exception {
// 查询所有酒店数据
List<Hotel> hotelList = hotelMapper.selectList(null);
// 1.创建request
BulkRequest request = new BulkRequest();
// 2.准备DSL
for (Hotel hotel : hotelList) {
// 2-1 转为文档类型
HotelDoc hotelDoc = new HotelDoc(hotel);
// 2-2 转为json
String json = JSON.toJSONString(hotelDoc);
// 2-3 新增document
request.add(
new IndexRequest("hotel")
.id(hotelDoc.getId().toString())
.source(json, XContentType.JSON)
);
}
// 3.发送请求
client.bulk(request, RequestOptions.DEFAULT);
}