RestClient 访问elasticsearch

1。引入依赖

1)引入es的RestHighLevelClient依赖:

<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
</dependency>

2)因为SpringBoot默认的ES版本是7.6.2,所以我们需要覆盖默认的ES版本:

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

3)初始化RestHighLevelClient:

初始化的代码如下:

RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(
        HttpHost.create("http://192.168.150.101:9200")
));

2.创建索引库和删除索引库

存储的是新增索引库的语句

package cn.itcast.hotel;

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" +
            "}";
}

新增和删除索引库操作 

import org.apache.http.HttpHost;
import org.apache.http.client.methods.HttpPost;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.common.xcontent.XContentType;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.IOException;

@SpringBootTest
class HotelSuoYinTest {
    private RestHighLevelClient client;

    @BeforeEach
    void setup() {
        this.client =
                new RestHighLevelClient(
                        RestClient.builder(
                                HttpHost.create("http://101.43.94.150:9200")
                        ));
    }

    @AfterEach
    void shutdown() throws IOException {
        this.client.close();
    }
//    indices()  有这个,就是索引库的操作
    @Test
    void test() throws IOException {
//        创建request对象
        CreateIndexRequest request = new CreateIndexRequest("hotel");
//        准备请求的参数 dsl语句
        request.source(HotelConstants.MAPPING_TEMPLATE, XContentType.JSON);
//        发送请求
        client.indices().create(request, RequestOptions.DEFAULT);
    }

    @Test
    void deltest() throws IOException {
//        创建request对象
        DeleteIndexRequest request = new DeleteIndexRequest("hotel");
//        发送请求
        client.indices().delete(request, RequestOptions.DEFAULT);
    }
}

判断索引库是不是存在 

@Test
void testExistsHotelIndex() throws IOException {
    // 1.创建Request对象
    GetIndexRequest request = new GetIndexRequest("hotel");
    // 2.发送请求
    boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
    // 3.输出
    System.err.println(exists ? "索引库已经存在!" : "索引库不存在!");
}

索引库操作的基本步骤:

  • 初始化RestHighLevelClient

  • 创建XxxIndexRequest。XXX是Create、Get、Delete

  • 准备DSL( Create时需要,其它是无参)

  • 发送请求。调用RestHighLevelClient#indices().xxx()方法,xxx是create、exists、delete

3.删除文档 修改文档 新增文档 批量添加文档

因为mysql查询出来的hotel信息经纬度信息是分开的,但是eleasticsearch的地理坐标要求是一个String类型,中间用逗号分开,所以要转为hotelDoc


//文档,相当于mysql中的行
//#查询一条文档(记录)的 dsl语句
//        GET /heima/_doc/1
@SpringBootTest
public class DocumentTest {
    private RestHighLevelClient client;
    @Autowired
    HotelService hotelService;

    //    插入新数据
    @Test
    public void testadd() throws IOException {
        Hotel hotel = hotelService.getById(61083L);
        HotelDoc hotelDoc = new HotelDoc(hotel);
//        创建request,并指明要处理的索引是hotel,记录号是 hotelDoc.getId()
        IndexRequest request = new IndexRequest("hotel").id(hotelDoc.getId().toString());
        request.source(JSON.toJSONString(hotelDoc), XContentType.JSON);
        client.index(request, RequestOptions.DEFAULT);
    }

    //    查询某条数据
    @Test
    public void testquery() throws IOException {
        GetRequest request = new GetRequest("hotel", "61083");
        GetResponse response = client.get(request, RequestOptions.DEFAULT);
        String json = response.getSourceAsString();
        HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
        System.out.println(hotelDoc);
    }

    //更新某条数据
    @Test
    public void testupdate() throws IOException {
        Hotel hotel = hotelService.getById(61083L);
        HotelDoc hotelDoc = new HotelDoc(hotel);
        UpdateRequest request = new UpdateRequest("hotel", "61083");
        request.doc("price", "952");
        request.doc("address", "北京饭店");
        client.update(request, RequestOptions.DEFAULT);
    }

    //   删除某条数据
    @Test
    void testDeleteDocument() throws IOException {
        // 1.准备Request
        DeleteRequest request = new DeleteRequest("hotel", "61083");
        // 2.发送请求
        client.delete(request, RequestOptions.DEFAULT);
    }

    @Test
    void testpiliangadd() throws IOException {
        List<Hotel> hotels = hotelService.list();
        BulkRequest request = new BulkRequest();
        for (Hotel hotel : hotels) {
            HotelDoc hotelDoc = new HotelDoc(hotel);
            request.add(new IndexRequest("hotel")
                    .id(hotelDoc.getId() + "")
                    .source(JSON.toJSONString(hotelDoc)
                            , XContentType.JSON));
        }
        client.bulk(request, RequestOptions.DEFAULT);
    }

    @BeforeEach
    void setup() {
        this.client =
                new RestHighLevelClient(
                        RestClient.builder(
                                HttpHost.create("http://101.43.94.150:9200")
                        ));
    }

    @AfterEach
    void shutdown() throws IOException {
        this.client.close();
    }
}

4.查询文档

package cn.itcast.hotel;

import cn.itcast.hotel.pojo.HotelDoc;
import com.alibaba.fastjson.JSON;
import org.apache.http.HttpHost;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.IOException;
import java.util.Map;

@SpringBootTest
public class QueryTest {
    private RestHighLevelClient client;

    //查询全部文档
    @Test
    void testmatchall() throws IOException {
//       1. 准备request
        SearchRequest request = new SearchRequest("hotel");
//       2. 准备dsl
        request.source().query(QueryBuilders.matchAllQuery());
//        3.发送请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        handleResponse(response);
    }

    //全文检索查询
    @Test
    void testquerycheck() throws IOException {
//       1. 准备request
        SearchRequest request = new SearchRequest("hotel");

//       2. 准备dsl
        request.source().query(QueryBuilders.matchQuery("all", "如家"));
//        3.发送请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        handleResponse(response);
    }

    //boolean复合查询
    @Test
    void testBool() throws IOException {
        // 1.准备Request
        SearchRequest request = new SearchRequest("hotel");
        // 2.准备DSL
        // 2.1.准备BooleanQuery
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        // 2.2.添加term
        boolQuery.must(QueryBuilders.termQuery("city", "上海"));
        // 2.3.添加range
        boolQuery.filter(QueryBuilders.rangeQuery("price").lte(250));
//        关联查询条件
        request.source().query(boolQuery);
        // 3.发送请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        // 4.解析响应
        handleResponse(response);
    }

    //查询后排序和按页查询  el的分页查询是查询所有结果之后再分页。
    @Test
    void testpageandsort() throws IOException {
//        页码,每页大小
        int pagenum = 1, pagesize = 5;
        // 1.准备Request
        SearchRequest request = new SearchRequest("hotel");
        request.source().query(QueryBuilders.matchAllQuery());
        request.source().sort("price", SortOrder.ASC);
//       前端传过来的是页码和每页大小 ,算一下从第多少条后开始分页
        request.source().from((pagenum - 1) * pagesize);
//        页大小
        request.source().size(pagesize);
        // 3.发送请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        // 4.解析响应
        handleResponse(response);
    }

    //查询后高亮显示
    @Test
    void testhightlight() throws IOException {
        // 1.准备Request
        SearchRequest request = new SearchRequest("hotel");
        request.source().query(QueryBuilders.matchQuery("brand", "如家"));
//        requireFieldMatch(false) 搜索条件brand和高亮的属性name设为不一致
        request.source().highlighter(new HighlightBuilder().field("name").requireFieldMatch(false));
        // 3.发送请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        handleHeightLightResponse(response);
    }
    
//    高亮查询
    private void handleHeightLightResponse(SearchResponse response) {
        // 4.解析响应
        SearchHits searchHits = response.getHits();
        // 4.1.获取总条数
        long total = searchHits.getTotalHits().value;
        System.out.println("共搜索到" + total + "条数据");
        // 4.2.文档数组
        SearchHit[] hits = searchHits.getHits();
        // 4.3.遍历
        for (SearchHit hit : hits) {
            // 获取文档source
            String json = hit.getSourceAsString();
            // 反序列化
            HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
//             获取高亮
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            HighlightField highlightField = highlightFields.get("name");
            String name = highlightField.getFragments()[0].toString();
            hotelDoc.setName(name);
            System.out.println(hotelDoc);
        }
    }
// 解析响应函数
    private void handleResponse(SearchResponse response) {
        // 4.解析响应
        SearchHits searchHits = response.getHits();
        // 4.1.获取总条数
        long total = searchHits.getTotalHits().value;
        System.out.println("共搜索到" + total + "条数据");
        // 4.2.文档数组
        SearchHit[] hits = searchHits.getHits();
        // 4.3.遍历
        for (SearchHit hit : hits) {
            // 获取文档source
            String json = hit.getSourceAsString();
            // 反序列化
            HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
//            System.out.println("hotelDoc = " + hotelDoc);
        }
    }

    @BeforeEach
    void setup() {
        this.client =
                new RestHighLevelClient(
                        RestClient.builder(
                                HttpHost.create("http://101.43.94.150:9200")
                        ));
    }

    @AfterEach
    void shutdown() throws IOException {
        this.client.close();
    }
}

猜你喜欢

转载自blog.csdn.net/sharesb/article/details/128307064