ES文档操作 ,kibana-query查询

发布时间 2023-09-16 20:40:09作者: qd372502
package cn.itcast.hotel;

import cn.itcast.hotel.constant.EsConstant;
import cn.itcast.hotel.pojo.Hotel;
import cn.itcast.hotel.pojo.HotelDoc;
import cn.itcast.hotel.service.impl.HotelService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
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.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.lucene.search.function.CombineFunction;
import org.elasticsearch.common.unit.DistanceUnit;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.GeoDistanceSortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
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.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import javax.swing.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * d:文档操作 ,kibana-query查询
 * Description: TODO
 * ClassName: cn.itcast.hotel.HotelDocTest
 * Author: regular
 * Version: 1.0
 */
@SpringBootTest
public class HotelDocTest {
    @Autowired
    private HotelService hotelService;
    @Autowired
    private RestHighLevelClient client;
    /**
     * 根据ID查询文档
     * @Description: HotelDocTest
     */
    @Test
    public void getDocTest() throws IOException {
        GetRequest getRequest=new GetRequest(EsConstant.HOTEL_INDEX,"36934");
        //根据ID查询文档
        GetResponse response = client.get(getRequest, RequestOptions.DEFAULT);
        String json = response.getSourceAsString();
        HotelDoc hotelDoc= JSONObject.parseObject(json, HotelDoc.class);
        System.out.println(hotelDoc);
    }
    /**
     * 添加文档
     * @Description: HotelDocTest
     */
    @Test
    public void addDocTest() throws IOException {
        Hotel hotel=hotelService.getById(36934L);//根据ID查询
        HotelDoc hotelDoc=new HotelDoc(hotel);
        //创建增加文档的请求对象
        IndexRequest indexRequest=new IndexRequest(EsConstant.HOTEL_INDEX);
        //设置文档ID与数据
        indexRequest.id(hotelDoc.getId().toString()).source(JSONObject.toJSONString(hotelDoc), XContentType.JSON);
        //执行增加文档的请求
        IndexResponse response = client.index(indexRequest, RequestOptions.DEFAULT);
        String id= response.getId();
        System.out.println("id="+id);
    }
    /**
     * 删除文档
     * @Description: HotelDocTest
     */
    @Test
    public void deleteDocTest() throws IOException {
        DeleteRequest deleteRequest=new DeleteRequest(EsConstant.HOTEL_INDEX,"36934");
        DeleteResponse response = client.delete(deleteRequest, RequestOptions.DEFAULT);
        String id=response.getId();
        System.out.println("id=" + id);
    }
    /**
     * 修改文档
     * @Description: HotelDocTest
     */
    @Test
    public void updateDocTest(){
       Hotel hotel=hotelService.getById(36934L);
         HotelDoc hotelDoc=new HotelDoc(hotel);
         hotelDoc.setName("北京饭店");
         hotelDoc.setPrice(999);
         hotelDoc.setAddress("北京市东城区");
        UpdateRequest updateRequest=new UpdateRequest(EsConstant.HOTEL_INDEX,"36934");
        updateRequest.doc(JSONObject.toJSONString(hotelDoc),XContentType.JSON);
        try {
            UpdateResponse response = client.update(updateRequest, RequestOptions.DEFAULT);
            int status = response.status().getStatus();
            System.out.println(status);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * 批量操作文档
     * @Description: HotelDocTest
     * @Author: regular
     * @Version: 1.0
    */
    @Test
    public void bulkRequestTest(){
        List<Hotel> hotelList=hotelService.list(null);
        List<HotelDoc> hotelDocList=new ArrayList<>(hotelList.size());
        for (Hotel hotel : hotelList) {
            HotelDoc hotelDoc=new HotelDoc(hotel);
            hotelDocList.add(hotelDoc);
        }
        BulkRequest bulkRequest=new BulkRequest();
        for (HotelDoc hotelDoc : hotelDocList) {
            //向bulkRequest中添加多个indexRequest请求
            IndexRequest indexRequest=new IndexRequest(EsConstant.HOTEL_INDEX);
            indexRequest.id(hotelDoc.getId().toString()).source(JSONObject.toJSONString(hotelDoc),XContentType.JSON);
            bulkRequest.add(indexRequest);
        }
        //执行批量操作
        try {
            client.bulk(bulkRequest,RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 根据条件查询文档
     * @Description: HotelDocTest
     */
    @Test
    public void matchAllTest() throws IOException {
        //1.创建查询请求对象
        SearchRequest searchRequest=new SearchRequest(EsConstant.HOTEL_INDEX);
        //2.设置封装查询条件
        searchRequest.source().query(QueryBuilders.matchAllQuery());
        //3.执行查询
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        //4.解析查询结果
        printResult(response);
    }
    /**
     * 根据条件查询文档 multi_match
     * @Description: HotelDocTest
     */
    @Test
    public void matchMutiTest() throws IOException {
        SearchRequest searchRequest=new SearchRequest(EsConstant.HOTEL_INDEX);
        searchRequest.source().query(QueryBuilders.multiMatchQuery("北京","name","city","business"));
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        printResult(response);
    }
    //抽取方法返回es数据
    private void printResult(SearchResponse response) {
        long total = response.getHits().getTotalHits().value;
        System.out.println("total=" + total);
        SearchHit[] hits = response.getHits().getHits();
        for (SearchHit hit : hits) {
            String json = hit.getSourceAsString();
            HotelDoc hotelDoc = JSONObject.parseObject(json, HotelDoc.class);
            System.out.println(hotelDoc);
        }
    }
    /**
     * 根据条件查询文档 term
     * @Description: HotelDocTest
     */
    @Test
    public void termTest() throws IOException {
        SearchRequest searchRequest=new SearchRequest(EsConstant.HOTEL_INDEX);
        searchRequest.source().query(QueryBuilders.termQuery("city","北京"));
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        printResult(response);
    }
    /**
     * 根据条件查询文档 range
     * @Description: HotelDocTest
     */
    @Test
    public void rangeTest() throws IOException {
        SearchRequest searchRequest=new SearchRequest(EsConstant.HOTEL_INDEX);
        searchRequest.source().query(QueryBuilders.rangeQuery("price").gte(1000).lte(3000));
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        printResult(response);
    }
    /**
     * geo_distance
     * @Description: HotelDocTest
     * @Author: regular
     * @Version: 1.0
    */
    @Test
    public void geoDistanceTest() throws IOException {
        SearchRequest searchRequest=new SearchRequest(EsConstant.HOTEL_INDEX);
        searchRequest.source().query(QueryBuilders
                //指定字段
                .geoDistanceQuery("location")
                //指定距离
                .distance("5", DistanceUnit.KILOMETERS)
                //指定坐标
                .point(31.242201,121.509106));
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        printResult(response);//打印结果
    }
    /**
     * 复合查询 -算分查询(根据权重确认显示)
     * #给品牌是如家的酒店增加权重积分*10
     * @Description: HotelDocTest
     * @Author: regular
     * @Version: 1.0
    */
    @Test
    public void functionScoreTest() throws IOException {

        // 创建查询请求
        SearchRequest searchRequest = new SearchRequest("hotel");
        FunctionScoreQueryBuilder functionScoreQueryBuilder = new FunctionScoreQueryBuilder(
                //QueryBuilders.matchAllQuery(),
                QueryBuilders.termQuery("city", "上海"),
                new FunctionScoreQueryBuilder.FilterFunctionBuilder[]{
                        new FunctionScoreQueryBuilder.FilterFunctionBuilder(
                                QueryBuilders.termQuery("brand", "如家"),
                                ScoreFunctionBuilders.weightFactorFunction(10)
                        )
                }
        ).boostMode(CombineFunction.MULTIPLY);
        // 创建精确查询
        searchRequest.source().query(functionScoreQueryBuilder);
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        printResult(response);
    }
    /**
     * 复合查询 -布尔查询
     *
     * @Description: HotelDocTest
     * @Author: regular
     * @Version: 1.0
    */
    @Test
    public void boolTest() throws IOException {
        SearchRequest searchRequest=new SearchRequest(EsConstant.HOTEL_INDEX);
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        boolQueryBuilder.must(QueryBuilders.matchQuery("all","如家"))
                .mustNot(QueryBuilders.rangeQuery("price").gt(400))
                .filter(QueryBuilders.geoDistanceQuery("location").point(31.242201,121.509106).distance("5km"));
        searchRequest.source().query(boolQueryBuilder);
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        printResult(response);
    }
    /**
     * 搜索结果处理 -根据选定普通字段排序
     * @Description: HotelDocTest
     * @Author: regular
     * @Version: 1.0
     */
    @Test
    public void sortTest() throws IOException {
        SearchRequest searchRequest=new SearchRequest(EsConstant.HOTEL_INDEX);
        searchRequest.source()
                .query(QueryBuilders
                        //指定字段
                        .geoDistanceQuery("location")
                        //指定坐标
                        .point(31.242201,121.509106)
                        //指定距离
                        .distance("5",DistanceUnit.KILOMETERS))
                        //排序
                        .sort("score", SortOrder.DESC)
                        .sort("price", SortOrder.ASC);
        SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);
        printResult(response);
    }
    /**
     * 搜索结果处理 -根据地理坐标字段排序
     * @Description: HotelDocTest
     * @Author: regular
     * @Version: 1.0
     */
    @Test
    public void geoDistanceSortTest() throws IOException {
        SearchRequest searchRequest=new SearchRequest(EsConstant.HOTEL_INDEX);
        searchRequest.source()
                .query(QueryBuilders.matchAllQuery())
                //.sort(new GeoDistanceSortBuilder("location",31.242201,121.509106).order(SortOrder.ASC));
                .sort(
                        SortBuilders.geoDistanceSort("location",31.242201,121.509106)
                                .order(SortOrder.ASC)
                                .unit(DistanceUnit.KILOMETERS)
                );
        SearchResponse response= client.search(searchRequest, RequestOptions.DEFAULT);
        printResult(response);
    }
    /**
     * 距离升序、分页,有一个深度分页问题
     * @Description: HotelDocTest
     * @Author: regular
     * @Version: 1.0
    */
    @Test
    public void geoDistanceSortPageTest() throws IOException {
        SearchRequest searchRequest=new SearchRequest(EsConstant.HOTEL_INDEX);
        searchRequest.source()
                .query(QueryBuilders.matchAllQuery())
                //排序
                .sort(
                        SortBuilders.geoDistanceSort("location",31.242201,121.509106)
                                .order(SortOrder.ASC)
                                .unit(DistanceUnit.KILOMETERS)
                )
                .from(0)
                .size(3);
        SearchResponse response= client.search(searchRequest, RequestOptions.DEFAULT);
        printResult(response);
    }
    /**
     * 高亮显示
     * @Description: HotelDocTest
     * @Author: regular
     * @Version: 1.0
    */
    @Test
    public void highlightTest() throws IOException {
        SearchRequest searchRequest=new SearchRequest(EsConstant.HOTEL_INDEX);
        searchRequest.source()
                .query(QueryBuilders.matchQuery("all","如家"))
                .highlighter(
                        new HighlightBuilder()
                                .field("name")
                                .requireFieldMatch(false)
                                .preTags("<font color='red'>")
                                .postTags("</font>"))
                .from(20).size(20);
        SearchResponse response= client.search(searchRequest, RequestOptions.DEFAULT);
        long total = response.getHits().getTotalHits().value;
        System.out.println("总条数=" + total);
        for (SearchHit hit : response.getHits().getHits()) {
            String json = hit.getSourceAsString();
            System.out.println(json);
            HotelDoc hotelDoc = JSON.parseObject(json, HotelDoc.class);
            //获取高亮片段
            HighlightField highlightField = hit.getHighlightFields().get("name");
            String text = highlightField.getFragments()[0].toString();
            System.out.println(text);
            System.out.println(hotelDoc.getName());
        }
    }

}