利用JavaRestClient依赖使用java操作ES

引入依赖

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

这里可能会出现这种情况,我导入的是7.12.1的版本,但有两个maven依赖的版本并不是我们想要的7.12.1。

这是因为我们继承了spring-boot-starter-parent父工程,他的版本控制中限制了这两项的依赖的版本,所以我们需要再配置下图中的版本

下列代码为利用JavaRestClient对ES进行的CRUD操作

lsty为自己取得索引库名

package cn.itcast.hotel;

import cn.itcast.hotel.pojo.Hotel;
import cn.itcast.hotel.pojo.HotelDoc;
import cn.itcast.hotel.service.IHotelService;
import com.alibaba.fastjson.JSON;
import org.apache.http.HttpHost;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.GetIndexRequest;
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.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.IOException;
import java.util.List;

import static cn.itcast.hotel.constants.HotelConstants.MAPPING_TEMPLATE;

@SpringBootTest
public class HotelIndexTest {

    private RestHighLevelClient client;

    @Autowired
    private IHotelService hotelService;

    //创建索引库
    @Test
    void createIndex() throws IOException {
        CreateIndexRequest request = new CreateIndexRequest("lsty");
        request.source(MAPPING_TEMPLATE, XContentType.JSON); //MAPPING_TEMPLATE为一个json格式的字符串
        client.indices().create(request, RequestOptions.DEFAULT);
    }

    //删除索引库
    @Test
    void deleteIndex() throws IOException {
        DeleteIndexRequest request = new DeleteIndexRequest("lsty");
        client.indices().delete(request, RequestOptions.DEFAULT);
    }

    //查询索引库是否存在
    @Test
    void ExistsIndex() throws IOException {
        GetIndexRequest request = new GetIndexRequest("lsty");
        boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
        System.out.println(exists);
    }


    //向索引库添加文档
    @Test
    void testAddDocument() throws IOException {
        Hotel hotel = hotelService.getById(61083);//从数据库读取数据罢了,不重要
        
        HotelDoc hotelDoc = new HotelDoc(hotel);
        IndexRequest request = new IndexRequest("lsty").id(hotelDoc.getId().toString());
        request.source(JSON.toJSONString(hotelDoc),XContentType.JSON);
        client.index(request,RequestOptions.DEFAULT);
    }

    //删除文档
    @Test
    void testGetDocumentById() throws IOException {
        GetRequest request = new GetRequest("lsty","61083");
        GetResponse response = client.get(request, RequestOptions.DEFAULT);
        String json = response.getSourceAsString();
        System.out.println(json);
    }

    //更新文档(也可以直接用添加文档全面覆盖)
    @Test
    void testUpdateDocumentById() throws IOException {
        UpdateRequest request = new UpdateRequest("lsty","61083");
        request.doc(
                "price","182",
                "starName","三钻"
        );
        client.update(request,RequestOptions.DEFAULT);
    }

    //删除文档
    @Test
    void testDeleteDocumentById() throws IOException {
        DeleteRequest request = new DeleteRequest("lsty","61083");
        client.delete(request,RequestOptions.DEFAULT);
    }

    //批量操作文档
    @Test
    void testBulk() throws IOException {
        List<Hotel> list = hotelService.list(); //从数据库读取数据,不重要
        
        BulkRequest request = new BulkRequest();
        for (Hotel hotel:list){
            HotelDoc hotelDoc = new HotelDoc(hotel);
            request.add(new IndexRequest("lsty").id(hotelDoc.getId().toString()).source(JSON.toJSONString(hotelDoc),XContentType.JSON));
        }
        client.bulk(request,RequestOptions.DEFAULT);
    }

    //与ES创建链接
    @BeforeEach
    void setUp(){
        this.client = new RestHighLevelClient(RestClient.builder(
                HttpHost.create("http://192.168.230.100:9200")
        ));
    }

    //断开与ES的链接
    @AfterEach
    void tearDown() throws IOException {
        this.client.close();
    }


}

利用JavaRestClient进行搜索操作

import com.alibaba.fastjson.JSON;
import org.apache.http.HttpHost;
import org.apache.lucene.search.TotalHits;
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.common.geo.GeoPoint;
import org.elasticsearch.common.unit.DistanceUnit;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchAllQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.functionscore.FunctionScoreQueryBuilder;
import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortBuilders;
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 org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

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

@SpringBootTest
public class HotelSearchTest {

    private RestHighLevelClient client;

    //查找lsty索引库的所有数据
    @Test
    void testMatchAll() throws IOException {
        SearchRequest request = new SearchRequest("lsty");
        request.source().query(QueryBuilders.matchAllQuery());
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);

        handleResponse(response);
    }

    //查找all字段与“如家”有关的数据
    @Test
    void testMatch() throws IOException {
        SearchRequest request = new SearchRequest("lsty");
        request.source().query(QueryBuilders.matchQuery("all","如家"));
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);

        handleResponse(response);
    }

    //查找brand或name字段与“如家”有关的数据
    @Test
    void testMultiMatch() throws IOException {
        SearchRequest request = new SearchRequest("lsty");
        request.source().query(QueryBuilders.multiMatchQuery("如家","brand","name"));
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);

        handleResponse(response);
    }

    //查找city字段精确匹配为“北京”的数据
    @Test
    void testTerm() throws IOException {
        SearchRequest request = new SearchRequest("lsty");
        request.source().query(QueryBuilders.termQuery("city","北京"));
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);

        handleResponse(response);
    }

    //查找price字段为100~200区间的数据
    @Test
    void testRange() throws IOException {
        SearchRequest request = new SearchRequest("lsty");
        request.source().query(QueryBuilders.rangeQuery("price").gte(100).lte(200));
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);

        handleResponse(response);
    }

    //多子查询查找
    @Test
    void testBool() throws IOException {
        SearchRequest request = new SearchRequest("lsty");

        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must(QueryBuilders.termQuery("city","北京"));
        boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").lte(250));

        request.source().query(boolQueryBuilder);
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);

        handleResponse(response);
    }

    //查询所有数据,然后按价格排序
    @Test
    void testSort() throws IOException {
        SearchRequest request = new SearchRequest("lsty");

        request.source().query(QueryBuilders.matchAllQuery()); //查询数据
        request.source().from(0).size(5); //分页
        request.source().sort("price", SortOrder.ASC); //排序

        SearchResponse response = client.search(request, RequestOptions.DEFAULT);

        handleResponse(response);

    }

    //查询所有数据,然后按坐标距离排序
    @Test
    void testDistanceSort() throws IOException {
        SearchRequest request = new SearchRequest("lsty");

        request.source().query(QueryBuilders.matchAllQuery()); //查询数据
        request.source().sort(SortBuilders //排序
                .geoDistanceSort("location",new GeoPoint("31.221443, 121.41542"))
                .order(SortOrder.ASC)
                .unit(DistanceUnit.KILOMETERS)
        );

        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        handleResponse(response);
    }

    //高亮展示name字段中的酒店两字
    @Test
    void testHighlighter() throws IOException {
        SearchRequest request = new SearchRequest("lsty");
        request.source().query(QueryBuilders.matchQuery("name","酒店"));
        request.source().highlighter(new HighlightBuilder().field("name").requireFieldMatch(false));

        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        System.out.println(response);
        handleResponse(response);
    }

    //
    @Test
    void testFunctionScore() throws IOException {
        SearchRequest request = new SearchRequest("lsty");
//        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
//        boolQuery.must(QueryBuilders.matchAllQuery());
        
//        简单来说就是需要重新写分值时候不用request.source().query(QueryBuilders.matchAllQuery())
//        而是用下面的QueryBuilders.functionScoreQuery()
        FunctionScoreQueryBuilder functionScoreQuery = QueryBuilders.functionScoreQuery(QueryBuilders.matchAllQuery(),
                new FunctionScoreQueryBuilder.FilterFunctionBuilder[]{
                        new FunctionScoreQueryBuilder.FilterFunctionBuilder(
                                QueryBuilders.termQuery("isAD", true),
                                ScoreFunctionBuilders.weightFactorFunction(10)
                        )
                });

        request.source().query(functionScoreQuery);
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        handleResponse(response);
    }


    //输出数据处理
    private static void handleResponse(SearchResponse response) {
        SearchHits searchHits = response.getHits();

        TotalHits totalHits = searchHits.getTotalHits();
        System.out.println(totalHits);

        SearchHit[] hits = searchHits.getHits();
        for (SearchHit hit:hits){
            String json = hit.getSourceAsString();
            HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);

            //高亮展示(这里只是确定了只有name会高亮才这样写,其实健壮性还是不够的)
            Map<String, HighlightField> highlightFieldMap = hit.getHighlightFields();
            if (!CollectionUtils.isEmpty(highlightFieldMap)){
                HighlightField highlightField = highlightFieldMap.get("name");
                if (highlightField != null){
                    hotelDoc.setName(highlightField.getFragments()[0].string());
                }
            }

            //取出所有sort排序的分值,每个属性进行sort排序都会产生一个分值,存在数组里
            Object sortValues[] = hit.getSortValues();
            if (sortValues.length>0){
                Object sortValue = sortValues[0]; //这里我们默认只有一个距离排序的分值,所以直接取了[0]
                hotelDoc.setDistance(sortValue);
            }

            System.out.println(hotelDoc);
        }
    }

    //与ES创建链接
    @BeforeEach
    void setUp(){
        this.client = new RestHighLevelClient(RestClient.builder(
                HttpHost.create("http://192.168.230.100:9200")
        ));
    }

    //断开与ES的链接
    @AfterEach
    void tearDown() throws IOException {
        this.client.close();
    }


}

 

posted @ 2024-03-11 18:59  凌碎瞳缘  阅读(30)  评论(0编辑  收藏  举报