ES官方提供了各种不同语言的客户端,用来操作ES。这些客户端的本质就是组装DSL语句,通过http请求发送给ES。官方文档地址:https://www.elastic.co/guide/en/elasticsearch/client/index.html
其中的Java Rest Client又包括两种:
- Java Low Level Rest Client
 
- Java High Level Rest Client
 
mapping 映射分析
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
   | CREATE TABLE `tb_hotel` (   `id` bigint(20) NOT NULL COMMENT '酒店id',   `name` varchar(255) NOT NULL COMMENT '酒店名称;例:7天酒店',   `address` varchar(255) NOT NULL COMMENT '酒店地址;例:航头路',   `price` int(10) NOT NULL COMMENT '酒店价格;例:329',   `score` int(2) NOT NULL COMMENT '酒店评分;例:45,就是4.5分',   `brand` varchar(32) NOT NULL COMMENT '酒店品牌;例:如家',   `city` varchar(32) NOT NULL COMMENT '所在城市;例:上海',   `star_name` varchar(16) DEFAULT NULL COMMENT '酒店星级,从低到高分别是:1星到5星,1钻到5钻',   `business` varchar(255) DEFAULT NULL COMMENT '商圈;例:虹桥',   `latitude` varchar(32) NOT NULL COMMENT '纬度;例:31.2497',   `longitude` varchar(32) NOT NULL COMMENT '经度;例:120.3925',   `pic` varchar(255) DEFAULT NULL COMMENT '酒店图片;例:/img/1.jpg',   PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
   | 
 
创建索引库,最关键的是mapping映射,而mapping映射要考虑的信息包括:
- 字段名:可以参考数据表结构的名称和类型
 
- 字段数据类型:可以参考数据表结构的名称和类型
 
- 是否参与搜索:是否参与搜索要分析业务来判断
 
- 是否需要分词:内容如果是一个整体就无需分词,反之则要分词,分词器,我们可以统一使用ik_max_word
 
酒店数据的索引库结构:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
   | 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"       },       "starName":{         "type": "keyword"       },       "business":{         "type": "keyword"       },       "location":{         "type": "geo_point"       },       "pic":{         "type": "keyword",         "index": false       },       "all":{         "type": "text",         "analyzer": "ik_max_word"       }     }   } }
   | 
 
特殊字段说明:
- location:地理坐标,里面包含精度、纬度
 
- all:一个组合字段,其目的是将多字段的值 利用copy_to合并,提供给用户搜索
 
地理坐标说明:

copy_to说明:(支持多个字段搜索)

初始化 RestClient
在elasticsearch提供的API中,与elasticsearch一切交互都封装在一个名为RestHighLevelClient的类中,必须先完成这个对象的初始化,建立与elasticsearch的连接。
1.引入es的RestHighLevelClient依赖:
1 2 3 4
   | <dependency>     <groupId>org.elasticsearch.client</groupId>     <artifactId>elasticsearch-rest-high-level-client</artifactId> </dependency>
   | 
 
2.因为SpringBoot默认的ES版本是7.6.2,所以我们需要覆盖默认的ES版本:
1 2 3 4
   | <properties>     <java.version>1.8</java.version>     <elasticsearch.version>7.12.1</elasticsearch.version> </properties>
   | 
 
3.初始化RestHighLevelClient:
1 2 3
   | RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(         HttpHost.create("http://47.113.217.195:9200") ));
   | 
 
这里为了单元测试方便,我们创建一个测试类HotelIndexTest,然后将初始化的代码编写在@BeforeEach方法中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
   | package cn.itcast.hotel;
  import org.apache.http.HttpHost; import org.elasticsearch.client.RestHighLevelClient; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test;
  import java.io.IOException;
  public class HotelIndexTest {     private RestHighLevelClient client;
      @BeforeEach     void setUp() {         this.client = new RestHighLevelClient(RestClient.builder(                 HttpHost.create("http://47.113.217.195:9200")         ));     }
      @AfterEach     void tearDown() throws IOException {         this.client.close();     } }
   | 
 
创建索引库
创建索引库的API如下:

- 创建Request对象。因为是创建索引库的操作,因此Request是CreateIndexRequest。
 
- 添加请求参数,其实就是DSL的JSON参数部分。因为json字符串很长,这里是定义了静态字符串常量MAPPING_TEMPLATE,让代码看起来更加优雅。
 
- 发送请求,client.indices()方法的返回值是IndicesClient类型,封装了所有与索引库操作有关的方法。
 
定义mapping映射的JSON字符串常量:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
   | 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" +             "        \"copy_to\": \"all\"\n" +             "      },\n" +             "      \"starName\":{\n" +             "        \"type\": \"keyword\"\n" +             "      },\n" +             "      \"business\":{\n" +             "        \"type\": \"keyword\"\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" +             "}"; }
  | 
 
编写单元测试,实现创建索引:
1 2 3 4 5 6 7 8 9
   | @Test void createHotelIndex() throws IOException {          CreateIndexRequest request = new CreateIndexRequest("hotel");          request.source(MAPPING_TEMPLATE, XContentType.JSON);          client.indices().create(request, RequestOptions.DEFAULT); }
   | 
 
删除索引库
删除索引库的DSL语句非常简单:
与创建索引库相比:
- 请求方式从PUT变为DELTE
 
- 请求路径不变
 
- 无请求参数
 
三部曲
- 创建Request对象。这次是DeleteIndexRequest对象
 
- 准备参数。这里是无参
 
- 3)发送请求。改用delete方法
 
编写单元测试,实现删除索引:
1 2 3 4 5 6 7
   | @Test void testDeleteHotelIndex() throws IOException {          DeleteIndexRequest request = new DeleteIndexRequest("hotel");          client.indices().delete(request, RequestOptions.DEFAULT); }
   | 
 
判断索引库是否存在
判断索引库是否存在,本质就是查询,对应的DSL是:
三部曲
- 创建Request对象。这次是GetIndexRequest对象
 
- 准备参数。这里是无参
 
- 发送请求。改用exists方法
 
1 2 3 4 5 6 7 8 9
   | @Test void testExistsHotelIndex() throws IOException {          GetIndexRequest request = new GetIndexRequest("hotel");          boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);          System.err.println(exists ? "索引库已经存在!" : "索引库不存在!"); }
   | 
 
总结
JavaRestClient操作elasticsearch的流程基本类似。核心是client.indices()方法来获取索引库的操作对象。
索引库操作的基本步骤:
- 初始化RestHighLevelClient
 
- 创建XxxIndexRequest。XXX是Create、Get、Delete
 
- 准备DSL( Create时需要,其它是无参)
 
- 发送请求。调用RestHighLevelClient#indices().xxx()方法,xxx是create、exists、delete