当前位置:   article > 正文

RestClient操作es索引库_restclien连接es

restclien连接es

目录

1.首先引入RestHighLevelClient依赖

2.初始化client连接

3.创建es索引库

4.增删查改文档

根据id删除文档:

根据id查询文档:

修改指定文档:

5.批量将MySQL的数据存到ES

6.对于索引库的查询操作

普通查询:

高亮查询:

组合查询,将多个查询条件组合到一起的bool查询:

排序和分页查询:

基于地理位置查询附近的事物并按离的最近排序:


  内容基于黑马程序员学习记录,既然Elastic是基于Restful来进行操作的,那么肯定各种语言都有操作他的方式,这里我分享一下javaRestClient如何操作es索引库。

1.首先引入RestHighLevelClient依赖

  1. <dependency>
  2. <groupId>org.elasticsearch.client</groupId>
  3. <artifactId>elasticsearch-rest-high-level-client</artifactId>
  4. </dependency>
  5. <properties>
  6. <java.version>1.8</java.version>
  7. <!--因为springboot父工程默认es为7.6定义了版本所以需要根据自己的es版本在properties修改-->
  8. <elasticsearch.version>7.12.1</elasticsearch.version>
  9. </properties>

2.初始化client连接

在使用前要初始化连接,使用后要关闭连接

  1. private RestHighLevelClient client;
  2. /**
  3. * 建立es连接
  4. */
  5. @BeforeEach
  6. void setClient() {
  7. this.client = new RestHighLevelClient(RestClient.builder(
  8. HttpHost.create("http://ip:9200")
  9. ));
  10. }
  11. /**
  12. * 关闭连接
  13. * @throws IOException
  14. */
  15. @AfterEach
  16. void tearDown() throws IOException {
  17. this.client.close();
  18. }

3.创建es索引库

MAPPING_TEMPLATE为已经封装好的DSL建表语句,代码过长就进行了单独封装

  1. public class HotelConstants {
  2. public static final String MAPPING_TEMPLATE = "{\n" +
  3. " \"mappings\": {\n" +
  4. " \"properties\": {\n" +
  5. " \"id\":{\n" +
  6. " \"type\": \"keyword\"\n" +
  7. " },\n" +
  8. " \"name\":{\n" +
  9. " \"type\": \"text\",\n" +
  10. " \"analyzer\": \"ik_max_word\",\n" +
  11. " \"copy_to\": \"all\"\n" +
  12. " },\n" +
  13. " \"address\":{\n" +
  14. " \"type\": \"text\",\n" +
  15. " \"index\": false\n" +
  16. " },\n" +
  17. " \"price\":{\n" +
  18. " \"type\": \"integer\"\n" +
  19. " },\n" +
  20. " \"score\":{\n" +
  21. " \"type\": \"integer\"\n" +
  22. " },\n" +
  23. " \"brand\":{\n" +
  24. " \"type\": \"keyword\",\n" +
  25. " \"copy_to\": \"all\"\n" +
  26. " },\n" +
  27. " \"city\":{\n" +
  28. " \"type\": \"keyword\"\n" +
  29. " },\n" +
  30. " \"starName\":{\n" +
  31. " \"type\": \"keyword\"\n" +
  32. " },\n" +
  33. " \"business\":{\n" +
  34. " \"type\": \"keyword\",\n" +
  35. " \"copy_to\": \"all\"\n" +
  36. " },\n" +
  37. " \"location\":{\n" +
  38. " \"type\": \"geo_point\"\n" +
  39. " },\n" +
  40. " \"pic\":{\n" +
  41. " \"type\": \"keyword\",\n" +
  42. " \"index\": false\n" +
  43. " },\n" +
  44. " \"all\":{\n" +
  45. " \"type\": \"text\",\n" +
  46. " \"analyzer\": \"ik_max_word\"\n" +
  47. " }\n" +
  48. " }\n" +
  49. " }\n" +
  50. "}";
  51. }
  1. /**
  2. * 创建es索引库代码
  3. * @throws IOException
  4. */
  5. @Test
  6. void creatHotelIndex() throws IOException {
  7. //创建Request对象
  8. CreateIndexRequest request = new CreateIndexRequest("hotel");
  9. //准备请求的参数,DSL语句
  10. request.source(MAPPING_TEMPLATE, XContentType.JSON);
  11. //发送请求
  12. client.indices().create(request, RequestOptions.DEFAULT);
  13. }

4.增删查改文档

新增文档,这里是将数据库里的数据增添到es中,先调用service的接口查询数据,因为数据库中对于坐标的存放方式为横坐标、纵坐标,而es里是横纵坐标用,间隔拼接的字符串,所以用HotelDoc进行单独处理。

  1. @Data
  2. @NoArgsConstructor
  3. public class HotelDoc {
  4. private Long id;
  5. private String name;
  6. private String address;
  7. private Integer price;
  8. private Integer score;
  9. private String brand;
  10. private String city;
  11. private String starName;
  12. private String business;
  13. private String location;
  14. private String pic;
  15. public HotelDoc(Hotel hotel) {
  16. this.id = hotel.getId();
  17. this.name = hotel.getName();
  18. this.address = hotel.getAddress();
  19. this.price = hotel.getPrice();
  20. this.score = hotel.getScore();
  21. this.brand = hotel.getBrand();
  22. this.city = hotel.getCity();
  23. this.starName = hotel.getStarName();
  24. this.business = hotel.getBusiness();
  25. this.location = hotel.getLatitude() + ", " + hotel.getLongitude();
  26. this.pic = hotel.getPic();
  27. }
  28. }
  1. /**
  2. * 新增es文档
  3. * @throws IOException
  4. */
  5. @Test
  6. void testAddDocument() throws IOException {
  7. //根据id查询酒店
  8. Hotel hotel = hotelService.getById(61083L);
  9. //转换为文档信息
  10. HotelDoc hotelDoc = new HotelDoc(hotel);
  11. //准备request对象
  12. IndexRequest request = new IndexRequest("hotel").id(hotelDoc.getId().toString());
  13. //将hotel转换为json格式
  14. request.source(JSON.toJSONString(hotel),XContentType.JSON);
  15. //发送请求
  16. client.index(request,RequestOptions.DEFAULT);
  17. }

根据id删除文档:

  1. /**
  2. * 根据id删除文档
  3. * @throws IOException
  4. */
  5. @Test
  6. void testDelDocument() throws IOException {
  7. DeleteRequest request = new DeleteRequest("hotel","61083");
  8. client.delete(request,RequestOptions.DEFAULT);
  9. }

根据id查询文档:

  1. /**
  2. * 根据id查询es文档
  3. * @throws IOException
  4. */
  5. @Test
  6. void testGetDocumentById() throws IOException {
  7. GetRequest request = new GetRequest("hotel","61083");
  8. //发送请求,得到响应
  9. GetResponse response = client.get(request,RequestOptions.DEFAULT);
  10. String json = response.getSourceAsString();
  11. HotelDoc hotelDoc = JSON.parseObject(json,HotelDoc.class);
  12. System.out.println(hotelDoc);
  13. }

修改指定文档:

  1. /**
  2. * 更新es文档
  3. * @throws IOException
  4. */
  5. @Test
  6. void testUpdateDocument() throws IOException {
  7. UpdateRequest request = new UpdateRequest("hotel","61083");
  8. //准备修改的字段请求参数
  9. request.doc(
  10. "price" , "999",
  11. "starName" , "4星"
  12. );
  13. client.update(request,RequestOptions.DEFAULT);
  14. }

5.批量将MySQL的数据存到ES

实际是将很多新增文档语句整合在一起:

  1. /**
  2. * 批量添加文档
  3. */
  4. @Test
  5. void testBulkRequest() throws IOException {
  6. List<Hotel> hotels = hotelService.list();
  7. //准备request对象,BulkRequest实际是将多个index请求整合起来
  8. BulkRequest request = new BulkRequest();
  9. for (Hotel hotel : hotels) {
  10. HotelDoc hotelDoc = new HotelDoc(hotel);
  11. request.add(new IndexRequest("hotel")
  12. .id(hotelDoc.getId().toString())
  13. .source(JSON.toJSONString(hotelDoc),XContentType.JSON));
  14. }
  15. //发送请求
  16. client.bulk(request,RequestOptions.DEFAULT);
  17. }

6.对于索引库的查询操作

  对于查询结果的操作,因为es的高亮查询后高亮的字段是进行单独封装的,在highlight对象里,所以进行高亮显示的查询才进行相应的结果处理,不然会报数组为空:

cf2f3ac80c2e4910a97ee65658a80289.png

  1. private void handleResponse(SearchResponse response) {
  2. SearchHits searchHits = response.getHits();
  3. // 4.1.总条数
  4. long total = searchHits.getTotalHits().value;
  5. System.out.println("总条数:" + total);
  6. // 4.2.获取文档数组
  7. SearchHit[] hits = searchHits.getHits();
  8. // 4.3.遍历
  9. for (SearchHit hit : hits) {
  10. // 4.4.获取source
  11. String json = hit.getSourceAsString();
  12. // 4.5.反序列化,非高亮的
  13. HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
  14. // // 4.6.处理高亮结果
  15. // // 1)获取高亮map
  16. // Map<String, HighlightField> map = hit.getHighlightFields();
  17. // // 2)根据字段名,获取高亮结果
  18. // HighlightField highlightField = map.get("name");
  19. // // 3)获取高亮结果字符串数组中的第1个元素
  20. // String hName = highlightField.getFragments()[0].toString();
  21. // // 4)把高亮结果放到HotelDoc中
  22. // hotelDoc.setName(hName);
  23. // 4.7.打印
  24. System.out.println(hotelDoc);
  25. }
  26. }

普通查询:

  1. @Test
  2. void testMatch() throws IOException {
  3. // 1.准备request
  4. SearchRequest request = new SearchRequest("hotel");
  5. // 2.准备请求参数
  6. //查所有 request.source().query(QueryBuilders.matchAllQuery());
  7. //全文检索查一个字段满足的数据 request.source().query(QueryBuilders.matchQuery("all", "外滩如家"));
  8. //全文检索查多个字段满足 request.source().query(QueryBuilders.multiMatchQuery("外滩如家", "name", "brand", "city"));
  9. //精确查询位置为北京 request.source().query(QueryBuilders.termQuery("city","北京"));
  10. //精确查询价格<=250的酒店,lt: <,gt: >,gte: >=
  11. // request.source().query(QueryBuilders.rangeQuery("price").lte(250));
  12. //精确查询地图矩形范围内酒店,分别为上经度左纬度下经度右纬度
  13. //request.source().query(QueryBuilders.geoBoundingBoxQuery("location").setCorners(top, left, bottom, right));
  14. // 3.发送请求,得到响应
  15. SearchResponse response = client.search(request, RequestOptions.DEFAULT);
  16. // 4.结果解析
  17. handleResponse(response);
  18. }

 为了节省时间和内存,对于多字段的全文检索查询一般都是在建索引库时将多个需要全文检索的字段copy到一起,比如这里的all。

高亮查询:

  1. void testHighlight() throws IOException {
  2. // 1.准备request
  3. SearchRequest request = new SearchRequest("hotel");
  4. // 2.准备请求参数
  5. // 2.1.query
  6. request.source().query(QueryBuilders.matchQuery("all", "外滩如家"));
  7. // 2.2.高亮,es默认情况下高亮字段必须与搜索字段匹配,但是也可以通过requireFieldMatch(false)关闭
  8. request.source().highlighter(new HighlightBuilder().field("name").requireFieldMatch(false));
  9. // 3.发送请求,得到响应
  10. SearchResponse response = client.search(request, RequestOptions.DEFAULT);
  11. // 4.结果解析
  12. handleResponse(response);
  13. }

组合查询,将多个查询条件组合到一起的bool查询:

•must:必须匹配的条件,可以理解为“与”
•should:选择性匹配的条件,可以理解为“或”
•must_not:必须不匹配的条件
•filter:必须匹配的条件
  1. void testBool() throws IOException {
  2. // 1.准备request
  3. SearchRequest request = new SearchRequest("hotel");
  4. // 2.准备请求参数
  5. /*
  6. BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
  7. // 2.1.must
  8. boolQuery.must(QueryBuilders.termQuery("city", "杭州"));
  9. // 2.2.filter
  10. boolQuery.filter(QueryBuilders.rangeQuery("price").lte(250));
  11. */
  12. request.source().query(
  13. QueryBuilders.boolQuery()
  14. .must(QueryBuilders.termQuery("city", "杭州"))
  15. .filter(QueryBuilders.rangeQuery("price").lte(250))
  16. );
  17. // 3.发送请求,得到响应
  18. SearchResponse response = client.search(request, RequestOptions.DEFAULT);
  19. // 4.结果解析
  20. handleResponse(response);
  21. }

排序和分页查询:

  1. void testSortAndPage() throws IOException {
  2. //前端传页数和每页数量
  3. int page = 1,size = 5;
  4. // 1.准备request
  5. SearchRequest request = new SearchRequest("hotel");
  6. // 2.准备请求参数
  7. // 2.1.query
  8. request.source()
  9. .query(QueryBuilders.matchAllQuery());
  10. // 2.2.排序sort
  11. request.source().sort("price", SortOrder.ASC);
  12. // 2.3.分页 from\size
  13. request.source().from((page - 1) * size).size(size);
  14. // 3.发送请求,得到响应
  15. SearchResponse response = client.search(request, RequestOptions.DEFAULT);
  16. // 4.结果解析
  17. handleResponse(response);
  18. }

基于地理位置查询附近的事物并按离的最近排序:

  1. void testNeighborhood() throws IOException {
  2. // 1.准备request
  3. SearchRequest request = new SearchRequest("hotel");
  4. // 2.准备请求参数
  5. // 查询十公里内酒店
  6. request.source().query(
  7. QueryBuilders.geoDistanceQuery("location")
  8. .distance("10km")
  9. .point(new GeoPoint(39.914539, 116.413392)));
  10. // 构建GeoDistanceSortBuilder设置按距离排序参数
  11. GeoDistanceSortBuilder geoDistanceSortBuilder = SortBuilders.geoDistanceSort("location", new GeoPoint(39.914539, 116.413392));
  12. // 升序排序
  13. geoDistanceSortBuilder.order(SortOrder.ASC);
  14. request.source().sort(geoDistanceSortBuilder);
  15. // 3.发送请求,得到响应
  16. SearchResponse response = client.search(request, RequestOptions.DEFAULT);
  17. // 4.结果解析
  18. handleResponse(response);
  19. }

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/68558
推荐阅读
相关标签
  

闽ICP备14008679号