RestClient操作Elasticsearch(Java)

发布于:2024-04-19 ⋅ 阅读:(17) ⋅ 点赞:(0)

Es官方提供了各种不用语言的客户端,用来操作Es,这些客户端的本质就是组装DSL语句,通过http请求发送给Es,从而简化操作

es基础篇不熟悉参考一下博客:ElasticSearch入门篇-CSDN博客文章浏览阅读445次,点赞7次,收藏3次。Elasticsearch是一个开源的高扩展的分布式全文检索引擎,它可以近乎实时的存储、检索数据;本身扩展性很好,可以扩展到上百台服务器,处理PB级别的数据。es也使用Java开发并使用Lucene作为其核心来实现所有索引和搜索的功能,但是它的目的是通过简单的RESTful API来隐藏Lucene的复杂性,从而让全文搜索变得简单个开源的分布式搜索引擎,可以用来实现搜索,日志统计,分析,系统监控等多种功能。https://blog.csdn.net/qq_63837759/article/details/137744756?spm=1001.2014.3001.5501

环境准备

我们创建一张hotel-酒店表,然后插入几条数据,基于酒店表做后续的代码书写

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for tb_hotel
-- ----------------------------
DROP TABLE IF EXISTS `tb_hotel`;
CREATE TABLE `tb_hotel`  (
  `id` bigint NOT NULL COMMENT '酒店id',
  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '酒店名称',
  `address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '酒店地址',
  `price` int NOT NULL COMMENT '酒店价格',
  `score` int NOT NULL COMMENT '酒店评分',
  `brand` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '酒店品牌',
  `city` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '所在城市',
  `star_name` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '酒店星级,1星到5星,1钻到5钻',
  `business` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '商圈',
  `latitude` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '纬度',
  `longitude` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '经度',
  `pic` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '酒店图片',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = COMPACT;

-- ----------------------------
-- Records of tb_hotel
-- ----------------------------
INSERT INTO `tb_hotel` VALUES (36934, '7天连锁酒店(上海宝山路地铁站店)', '静安交通路40号', 336, 37, '7天酒店', '上海', '二钻', '四川北路商业区', '31.251433', '121.47522', 'https://m.tuniucdn.com/fb2/t1/G1/M00/3E/40/Cii9EVkyLrKIXo1vAAHgrxo_pUcAALcKQLD688AAeDH564_w200_h200_c1_t0.jpg');
INSERT INTO `tb_hotel` VALUES (38609, '速8酒店(上海赤峰路店)', '广灵二路126号', 249, 35, '速8', '上海', '二钻', '四川北路商业区', '31.282444', '121.479385', 'https://m.tuniucdn.com/fb2/t1/G2/M00/DF/96/Cii-TFkx0ImIQZeiAAITil0LM7cAALCYwKXHQ4AAhOi377_w200_h200_c1_t0.jpg');
INSERT INTO `tb_hotel` VALUES (38665, '速8酒店上海中山北路兰田路店', '兰田路38号', 226, 35, '速8', '上海', '二钻', '长风公园地区', '31.244288', '121.422419', 'https://m.tuniucdn.com/fb2/t1/G2/M00/EF/86/Cii-Tlk2mV2IMZ-_AAEucgG3dx4AALaawEjiycAAS6K083_w200_h200_c1_t0.jpg');
INSERT INTO `tb_hotel` VALUES (38812, '7天连锁酒店(上海漕溪路地铁站店)', '徐汇龙华西路315弄58号', 298, 37, '7天酒店', '上海', '二钻', '八万人体育场地区', '31.174377', '121.442875', 'https://m.tuniucdn.com/fb2/t1/G2/M00/E0/0E/Cii-TlkyIr2IEWNoAAHQYv7i5CkAALD-QP2iJwAAdB6245_w200_h200_c1_t0.jpg');


SET FOREIGN_KEY_CHECKS = 1;

接下来基于酒店表的数据结构自行分析创建对应的索引表:


PUT /hotel
{
  "mappings": {
    "properties": {
      "all":{
        "type": "text",
        "analyzer": "ik_max_word"
      },
      "id":{
        "type": "keyword"
      },
      "name":{
        "type": "text",
        "analyzer": "ik_smart",
        "copy_to": "all"
      },
      "address":{
        "type": "text",
        "index": false
      },
      "price":{
        "type": "long",
        "index": false
      },
      "score":{
        "type": "keyword"
      },
      "brand":{
        "type": "keyword",
        "copy_to": "all"
      },
      "city":{
        "type": "keyword",
        "copy_to": "all"
      },
      "starName":{
        "type": "keyword",
        "copy_to": "all"
      },
      "business":{
        "type": "keyword",
        "index": false
      },
      "logitude":{
        "type": "geo_point" 
      },
      "pic":{
        "type": "keyword"
      }
      
    }
  }
}

其中需要注意的是一般搜索酒店会根据名称,城市,评分等多种字段去搜索,每一个字段去创建倒排索引,需要查询很多词,效率低下,于是es支持 我们将这些字段集合到一个自定义的字段中,这个字段不会出现在索引库中,但是查询是按照他来查询。这就是all这个字段的含义。

使用RestClient来操作索引库

1,引入es的RestLevelClient

         <!--es依赖-->
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
        </dependency>

2,修改es版本

因为我们使用的springboot他会综艺的管理依赖,而我们使用的springboot管理的es版本和我们使用的es版本不一致,所以我们需要覆盖springboot的es版本

 <properties>
        <java.version>1.8</java.version>
        <elasticsearch.version>7.12.1</elasticsearch.version>
    </properties>

3,初始化RestLevelClient

我们这里书写一个测试类完成初始化


@SpringBootTest
public class HotelIndexTest {

    private RestHighLevelClient restHighLevelClient;

    //初始化es客户端,在代码执行之前先初始化好
    @BeforeEach
    public void setUp(){
        this.restHighLevelClient=new RestHighLevelClient(RestClient.builder(
                HttpHost.create("http://192.168.101.100:9200")
        ));
    }
    //销毁
    @AfterEach
    public void close() throws IOException {
        restHighLevelClient.close();
    }
}

4,使用java代码创建索引库

 @Test
    void createIndex() throws IOException {
        //1,创建request请求对象
        CreateIndexRequest request = new CreateIndexRequest("索引库名称");
        //2,封装请求参数
        request.source(IndexMapping.HotelIndexMapping, XContentType.JSON);
        //3,发起请求
        restHighLevelClient.indices().create(request, RequestOptions.DEFAULT);
        //restHighLevelClient.search()
    }

5,使用java代码删除索引库

RestClient实现文档增删改查

1,增加一条文档

    /**
     * 插入一条文档
     * @throws IOException
     */
    @Test
    void insertWord() throws IOException {
        Hotel hotel = hotelService.getById(39106);
        //创建request请求对象,设置需要插入的文档的索引名,id
        IndexRequest indexRequest=new IndexRequest("hotel").id(hotel.getId().toString());
        HotelDoc hotelDoc = new HotelDoc(hotel);
        //封装请求参数
        indexRequest.source(JSON.toJSONString(hotelDoc),XContentType.JSON);
        //发起请求
        restHighLevelClient.index(indexRequest,RequestOptions.DEFAULT);
    }

  

2,删除一条文档


    /**
     * 删除一条文档
     * @throws IOException
     */
    @Test
    void deleteWord() throws IOException {
        DeleteRequest request=new DeleteRequest("hotel","39106");
        DeleteResponse delete = restHighLevelClient.delete(request, RequestOptions.DEFAULT);

        System.out.println(delete.getIndex());
    }

3,修改一条文档


    /**
     * 更新文档
     * @throws IOException
     */
    @Test
    void updateWord() throws IOException {
        UpdateRequest request=new UpdateRequest("hotel","39106");
        Map<String, Object> doc=new HashMap<>();
        doc.put("name","修改之后-7天连锁酒店(上海莘庄地铁站店)");
        doc.put("price",999);
        request.doc(doc);
        restHighLevelClient.update(request,RequestOptions.DEFAULT);

    }

   

4,查询一条文档


    /**
     * 查询一条文档
     * @throws IOException
     */
    @Test
    void searchWord() throws IOException {
        //按照id查询文档
        GetRequest request=new GetRequest("hotel","39106");
        GetResponse response = restHighLevelClient.get(request, RequestOptions.DEFAULT);

        String sourceAsString = response.getSourceAsString();
        System.out.println(sourceAsString);

        //将查询到的json文档重新解析为java对象
        HotelDoc hotelDoc = JSON.parseObject(sourceAsString, HotelDoc.class);
        System.out.println(hotelDoc);
        //输出当前文档属于那个索引库
        String index = response.getIndex();
        System.out.println("index:"+index);

        //将每个字段输出  例如 score=41, address=闵行莘庄镇七莘路299号
        Map<String, Object> source = response.getSource();
        System.out.println("source:"+source);
    }

   

5,批量插入多条文档

  /**
     * 批量插入多条文档
     * @throws IOException
     */
    @Test
    void insertWords() throws IOException {
        //只查询十条数据
        Page<Hotel> page = new Page<>(2,10);
        IPage<Hotel> pageResult = hotelService.page(page);
        List<Hotel> hotelList = pageResult.getRecords();
        BulkRequest request = new BulkRequest();
        hotelList.forEach(hotel -> {
            request.add(new IndexRequest("hotel")
                    .id(hotel.getId().toString())
                    .source(JSON.toJSONString(hotel),XContentType.JSON));
        });
        restHighLevelClient.bulk(request,RequestOptions.DEFAULT);
    }


至此,使用RestClient对es基本操作完结!!!