赞
踩
RestClient是es官方提供的一套用于通过代码操作es的api,es官方提供了不同语言的客户端,这些客户端本质上就是组装的DSL语句,通过http请求发送给es
在kibana中设置
使用es需要引入对应的依赖,注意依赖版本要和es版本一致
<dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-high-level-client</artifactId> </dependency>
因为SpringBoot默认的ES版本是7.6.2,所以我们需要覆盖默认的ES版本:
<properties>
<java.version>1.8</java.version>
<elasticsearch.version>7.12.1</elasticsearch.version>
</properties>
创建一个测试类,先初始化RestHighLevelClient,连接到es,代码如下
- import java.io.IOException;
-
- public class HotelIndexTest {
- private RestHighLevelClient client;
-
- //声明对象,并做对象初始化连接到es,提高代码复用性
- @BeforeEach
- void setUp(){
- this.client = new RestHighLevelClient(RestClient.builder(
- HttpHost.create("http://192.168.61.130:9200")
- ));
- }
-
- @AfterEach
- void tearDown() throws IOException {
- this.client.close();
- }
- }
成功后创建一个新的索引库,这里的DSL语句需要我们手动编写或者自己引入,我先新建一个类,写好DSL语句,在Dev Tools写一个,然后复制到代码里去,如下
- public class HotelConstants {
- public 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" +
- " \"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" +
- "}";
- }
然后写新增索引库的方法,并将刚才的DSL语句引入到下面代码中,如下
- @Test
- void createHotelIndex() throws IOException {
- //1,创建Request对象
- CreateIndexRequest request = new CreateIndexRequest("hotel");
- //2,准备请求的参数:DSL语句
- request.source(MAPPING_TEMPLATE, XContentType.JSON);
- //3,发送请求
- client.indices().create(request, RequestOptions.DEFAULT);
- }
- //删除索引库
- @Test
- void testDeleteHotelIndex() throws IOException {
- //创建删除对象
- DeleteIndexRequest request = new DeleteIndexRequest("hotel");
- //删除请求
- client.indices().delete(request,RequestOptions.DEFAULT);
- }
- //判断索引是否存在
- @Test
- void testExistsHotelIndex() throws IOException {
- //查看索引库
- GetIndexRequest getIndexRequest = new GetIndexRequest("hotel");
- //判断索引库是否存在
- boolean exists = client.indices().exists(getIndexRequest, RequestOptions.DEFAULT);
-
- System.out.println(exists ? "索引库存在":"索引库不存在" );//打印true或者false判断索引库是否存在
-
- }
新增文档:通常情况新增的数据都是从数据库导入的,所以需要先连接数据库并查到数据,并且根据数据库的字段创建对应的索引库,然后才是导入数据,先创建pojo对象,这里取名Hotel,
- @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中经纬度是将这两个字段拼接起来的一个字段,格式不同所以要做转换,所以要再写一个pojo对象这里叫做HotelDoc
- @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;
-
- 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();
- }
- }
新建一个测试类,通过mybatisplus查询数据库内的内容上传到es中
- @SpringBootTest
- public class HotelDocumentTest {
-
- @Autowired
- private IHotelService hotelService;
-
- private RestHighLevelClient client;
-
- @Test
- void testAddDocument() throws IOException {
- //根据id查询数据
- Hotel hotel = hotelService.getById(61083L);
- //因为没有经纬度,设置了一个新实体类混合经纬度
- HotelDoc hotelDoc = new HotelDoc(hotel);
- //1.准备Request对象
- IndexRequest request = new IndexRequest("hotel").id(hotelDoc.getId().toString());
- //2.准备Json文档
- request.source(JSON.toJSON(hotelDoc),XContentType.JSON);
- //3.发送请求
- client.index(request,RequestOptions.DEFAULT);
- }
-
-
- //声明对象,并做对象初始化连接到es,提高代码复用性
- @BeforeEach
- void setUp(){
- this.client = new RestHighLevelClient(RestClient.builder(
- HttpHost.create("http://192.168.61.130:9200")
- ));
- }
-
- @AfterEach
- void tearDown() throws IOException {
- this.client.close();
- }
- }
查询操作
- @Test
- void testGetDocumentById() throws IOException {
- //准备request
- GetRequest request = new GetRequest("hotel", "61083");
- //发送请求得到响应
- GetResponse response = client.get(request, RequestOptions.DEFAULT);
- //解析响应结果
- String json = response.getSourceAsString();
- //反序列化json
- HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
- System.err.println(hotelDoc);
- }
删除操作
- @Test
- void deleteDocumentest() throws IOException {
- //1、准备request
- DeleteRequest request= new DeleteRequest("hotel", "61083");
- //2、发送请求
- client.delete(request,RequestOptions.DEFAULT);
- }
修改操作
方式一:全量更新。再次写入id一样的文档,就会删除旧文档,添加新文档
方式二:局部更新。只更新部分字段,我们演示方式二
- @Test
- void testUpdateDocumentById() throws IOException {
- //1,新建request对象
- UpdateRequest request = new UpdateRequest("hotel", "61083");
- //2.准备参数
- request.doc(
- "price","1000",
- "starName","四钻"
- );
- //3,发送请求
- client.update(request,RequestOptions.DEFAULT);
- }
批量数据导入操作
- void BulkRequest() throws IOException {
- //1、创建request
- BulkRequest bulkRequest = new BulkRequest();
- //批量查询数据库数据
- List<Hotel> list = hotelService.list();
- //遍历是因为数据库数据较多
- for (Hotel hotel : list) {
- //转换为文档类型
- HotelDoc hotelDoc = new HotelDoc(hotel);
- //2、准备参数,添加多个新增的Request
- bulkRequest.add(new IndexRequest("hotel").
- id(hotelDoc.getId().toString()).
- source(JSON.toJSONString(hotelDoc),XContentType.JSON));
- }//这里就是一个链式编程,直接调用了对象的方法,而不像之前是分步写
-
-
- //不理解遍历的,也可以 自己一条条数据的添加进去,如下,就是很麻烦
- /*bulkRequest.add(new IndexRequest("hotel").
- id("1").
- source(JSON.toJSONString(hotelDoc),XContentType.JSON));
- bulkRequest.add(new IndexRequest("hotel").
- id("2").
- source(JSON.toJSONString(hotelDoc),XContentType.JSON));
- bulkRequest.add(new IndexRequest("hotel").
- id("3").
- source(JSON.toJSONString(hotelDoc),XContentType.JSON));*/
-
-
- //3、发送请求
- client.bulk(bulkRequest,RequestOptions.DEFAULT);
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。