【SpringCloud】微服务技术栈入门6 - RestClient深入
目录
- RestClient
- 定义索引
- 安装与配置测试类
- 插入索引
- 索引的 CRUD
- 批量导入文档
RestClient
定义索引
引入对应 sql 后,需要添加 sql 对应的 es 索引
下面是根据 sql 结构来构建的索引树,我们需要插入到 es 里面,在这里先不要在 devtools 中实现,下一节我们将会使用 restclient 来插入这个索引
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"
},
"starName":{
"type": "keyword"
},
"business":{
"type": "keyword",
"copy_to": "all"
},
"location":{
"type": "geo_point"
},
"pic":{
"type": "keyword",
"index": false
},
"all":{
"type": "text",
"analyzer": "ik_max_word"
}
}
}
}
copy_to
字段的作用是将当前字段附加到另外一个字段内,当搜索时就会联合被附加的字段一起搜索
比如上面将 business、brand 和 name 均附加到了 all 字段上,而被附加的 all 并不会额外添加内容,只是被搜索时他们三个会同时被检索,提高效率,仅此而已
安装与配置测试类
pom 内添加 es 依赖项,这里先略去版本
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
</dependency>
然后到 properties 标签内添加 es 的版本,注意这里的版号一定要和你使用的 es 版本严格相等!
比如我这边用的是 es7.8.0,就必须是这个版本!
<properties>
<java.version>1.8</java.version>
<elasticsearch.version>7.8.0</elasticsearch.version>
</properties>
新建一个测试类,使用注解 @BeforeEach
和 @AfterEach
来实现 restclient
链接与关闭的两大事务
@SpringBootTest
public class HotelIndexTest {
private RestHighLevelClient client;
@BeforeEach
void setup() {
this.client = new RestHighLevelClient(RestClient.builder(
HttpHost.create("http://localhost:9200")
));
}
@AfterEach
void destory() throws IOException {
client.close();
}
}
插入索引
首先新建一个常量类,把插入索引的 json 保存到里面去
这段文本就是上上一节定义的插入索引 json
package cn.itcast.hotel.constant;
public class HotelConst {
public static final String HOTEL_INDEX = "{\n" +
" \"mappings\": {\n" +
" \"properties\": {\n" +
" \"id\":{\n" +
" \"type\": \"keyword\"\n" +
" },\n" +
" \"name\":{\n" +
" \"type\": \"text\",\n" +
" \"analyzer\": \"ik_max_word\",\n" +
" \"copy_to\": \"all\"\n" +
" },\n" +
" \"address\":{\n" +
" \"type\": \"keyword\",\n" +
" \"index\": false\n" +
" },\n" +
" \"price\":{\n" +
" \"type\": \"integer\"\n" +
" },\n" +
" \"score\":{\n" +
" \"type\": \"integer\"\n" +
" },\n" +
" \"brand\":{\n" +
" \"type\": \"keyword\",\n" +
" \"copy_to\": \"all\"\n" +
" },\n" +
" \"city\":{\n" +
" \"type\": \"keyword\"\n" +
" },\n" +
" \"starName\":{\n" +
" \"type\": \"keyword\"\n" +
" },\n" +
" \"business\":{\n" +
" \"type\": \"keyword\",\n" +
" \"copy_to\": \"all\"\n" +
" },\n" +
" \"location\":{\n" +
" \"type\": \"geo_point\"\n" +
" },\n" +
" \"pic\":{\n" +
" \"type\": \"keyword\",\n" +
" \"index\": false\n" +
" },\n" +
" \"all\":{\n" +
" \"type\": \"text\",\n" +
" \"analyzer\": \"ik_max_word\"\n" +
" }\n" +
" }\n" +
" }\n" +
"}";
}
紧接着在测试类中编写插入 index 的方法即可
@Test
void testCreateIndex() throws IOException {
// 创建索引请求
CreateIndexRequest request = new CreateIndexRequest("hotel");
// 设置索引的源数据
request.source(HotelConst.HOTEL_INDEX, XContentType.JSON);
// 使用客户端执行创建索引请求
client.indices().create(request, RequestOptions.DEFAULT);
}
你可以使用以下两个测试方法来实现删除索引以及判断对应索引存在与否
// 删除索引
@Test
void testDeleteIndex() throws IOException {
DeleteIndexRequest request = new DeleteIndexRequest("hotel");
client.indices().delete(request, RequestOptions.DEFAULT);
}
// 通过get索引,判断get请求的返回值来看索引是否已经创建
@Test
void testExistIndex() throws IOException {
GetIndexRequest request = new GetIndexRequest("hotel");
boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
System.out.println(exists);
}
索引的 CRUD
创建索引
首先引入 IHotelService
用来通过 id 查询 mysql 对应记录
然后通过 JSON.toJSONString
把对应的实体类转换为 JSON 字符串的格式用来创建索引
@SpringBootTest
public class ElasticSearchCRUDTest {
@Autowired
private IHotelService hotelService;
private RestHighLevelClient client;
@Test
void testIndexDoc() throws IOException {
Hotel hotelServiceById = hotelService.getById(61083L);
HotelDoc hotelDoc = new HotelDoc(hotelServiceById);
IndexRequest request = new IndexRequest("hotel").id(hotelServiceById.getId().toString());
request.source(JSON.toJSONString(hotelDoc), XContentType.JSON);
client.index(request, RequestOptions.DEFAULT);
}
}
根据指定 id 获取索引存储 JSON,并将其转换为实体类后输出
@Test
void testGetDoc() throws IOException{
GetRequest request= new GetRequest("hotel","61083");
GetResponse response = client.get(request, RequestOptions.DEFAULT);
String source = response.getSourceAsString();
HotelDoc hotelDoc = JSON.parseObject(source, HotelDoc.class);
System.out.println(hotelDoc);
}
更新字段
字段更新有两种方式
- 全量更新:删掉旧的,新建一个新的插进去
- 局部更新:在原来的基础上更新需要的内容
下面展示了局部更新的方法
@Test
void testUpdateDoc() throws IOException {
UpdateRequest request = new UpdateRequest("hotel", "61083");
request.doc(
"price", "2103",
"starName", "星钻"
);
client.update(request, RequestOptions.DEFAULT);
}
删除文档就更简单了,直接提供索引以及对应的 id 就好了
@Test
void testDeleteDoc() throws IOException{
DeleteRequest request = new DeleteRequest("hotel", "61083");
client.delete(request, RequestOptions.DEFAULT);
}
批量导入文档
使用 bulk 请求来实现批量索引查询
@Test
void testBulkImport() throws IOException {
BulkRequest request = new BulkRequest();
request.add(new IndexRequest("hotel").id("61083").source("json", XContentType.JSON));
request.add(new IndexRequest("hotel").id("61083").source("json", XContentType.JSON));
request.add(new IndexRequest("hotel").id("61083").source("json", XContentType.JSON));
client.bulk(request, RequestOptions.DEFAULT);
}
查询所有酒店后使用 bulk 将他们依次插入索引
@Test
void testBulkIndex() throws IOException {
List<Hotel> list = hotelService.list();
BulkRequest request = new BulkRequest();
for (Hotel hotel : list) {
HotelDoc hotelDoc = new HotelDoc(hotel);
request.add(
new IndexRequest("hotel")
.id(hotelDoc.getId().toString())
.source(JSON.toJSONString(hotelDoc), XContentType.JSON)
);
}
client.bulk(request, RequestOptions.DEFAULT);
}