ElasticSearch 入门(五)高级搜索

相关api请求格式(包括apipost直接请求服务器 和java api)

https://docs.apipost.cn/preview/1c41ba44325ab590/4aec43b07172edae

代码片段(请求说明以及java api书写格式全在一起)

    //region 高级搜索
    /**
     * 查询所有
     * matchAll
     * 将结果返回为goods对象 装载在list中
     * 3分页,默认显示10条
     */
    @GetMapping("matchAll")
    public void matchAll() throws IOException {

        //2构建查询请求对象,指定查询的索引名称
        SearchRequest searchResult = new SearchRequest("goods");
        //4创建 查询条件构建器
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //6查询条件
        MatchAllQueryBuilder queryBuilder = QueryBuilders.matchAllQuery();//查询所有文档
        //5指定查询
        sourceBuilder.query(queryBuilder);
        //3添加查询条件构建器
        searchResult.source(sourceBuilder);
        //8添加分页信息   from页码,size每页数量
        sourceBuilder.from(0);
        sourceBuilder.size(2);
        //1查询
        SearchResponse searchResponse = restHighLevelClient.search(searchResult, RequestOptions.DEFAULT);

        //7获取查询对象
        SearchHits searchHits = searchResponse.getHits();
        //7.1 获取总记录数
        long value = searchHits.getTotalHits().value;
        log.info("总记录数为:{}", value);

        //7.2获取hits数据数组
        List<Goods> objects = new ArrayList<>();
        SearchHit[] hits = searchHits.getHits();
        for (SearchHit hit : hits) {
            String sourceAsString = hit.getSourceAsString();
            //转化为goods对象
            Goods goods = JSON.parseObject(sourceAsString, Goods.class);
            objects.add(goods);
        }
        log.info("objects :{}", objects);
    }


    /**
     * term  词条查询
     *
     * @throws IOException
     */
    @GetMapping("termQuery")
    public void termQuery() throws IOException {
        SearchRequest searchRequest = new SearchRequest("goods");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//term词条查询
        TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("categoryName", "智能手机");
        searchSourceBuilder.query(termQueryBuilder);
        searchRequest.source(searchSourceBuilder);
        SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        SearchHits searchHits = search.getHits();
        //获取记录数
        long value = searchHits.getTotalHits().value;
        log.info("value:{}", value);

        List<Goods> objects = new ArrayList<>();
        SearchHit[] hits = searchHits.getHits();
        for (SearchHit hit : hits) {
            String sourceAsString = hit.getSourceAsString();
            //转化为goods对象
            Goods goods = JSON.parseObject(sourceAsString, Goods.class);
            objects.add(goods);
        }
        log.info("objects :{}", objects);
    }


    /**
     * match  词条查询  分词查询
     * 会对查询条件进行分词、
     * 然后将分词后的查询条件和词条进行等值匹配
     * 默认取并集(OR)
     *
     * @throws IOException
     */
    @GetMapping("matchQuery")
    public List<Goods> matchQuery() throws IOException {
        SearchRequest searchRequest = new SearchRequest("goods");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //match词条查询
        MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("title", "华为手机");
        matchQueryBuilder.operator(Operator.OR);//match取值方式 分词的交集或者并集
        searchSourceBuilder.query(matchQueryBuilder);
        searchRequest.source(searchSourceBuilder);
        SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        SearchHits searchHits = search.getHits();
        //获取记录数
        long value = searchHits.getTotalHits().value;
        log.info("value:{}", value);

        List<Goods> objects = new ArrayList<>();
        SearchHit[] hits = searchHits.getHits();
        for (SearchHit hit : hits) {
            String sourceAsString = hit.getSourceAsString();
            //转化为goods对象
            Goods goods = JSON.parseObject(sourceAsString, Goods.class);
            objects.add(goods);
        }
        log.info("objects :{}", objects);
        return objects;
    }


    /**
     * wildcard  模糊查询
     * wildcard查询:会对查询条件进行分词。还可以使用通配符? (任意单个字符)和* (0个或多个字符)
     *
     * @throws IOException
     */
    @GetMapping("wildcardQuery")
    public List<Goods> wildcardQuery() throws IOException {
        SearchRequest searchRequest = new SearchRequest("goods");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //wildcard  模糊查询  不能前缀模糊。否则会扫描每一条数据
        WildcardQueryBuilder wildcardQueryBuilder = QueryBuilders.wildcardQuery("title", "华为*");
        searchSourceBuilder.query(wildcardQueryBuilder);
        searchRequest.source(searchSourceBuilder);
        SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        SearchHits searchHits = search.getHits();
        //获取记录数
        long value = searchHits.getTotalHits().value;
        log.info("value:{}", value);

        List<Goods> objects = new ArrayList<>();
        SearchHit[] hits = searchHits.getHits();
        for (SearchHit hit : hits) {
            String sourceAsString = hit.getSourceAsString();
            //转化为goods对象
            Goods goods = JSON.parseObject(sourceAsString, Goods.class);
            objects.add(goods);
        }
        log.info("objects :{}", objects);
        return objects;
    }

    /**
     * regexp  模糊查询
     * 正则查询
     *
     * @throws IOException
     */
    @GetMapping("regexpQuery")
    public List<Goods> regexpQuery() throws IOException {
        SearchRequest searchRequest = new SearchRequest("goods");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //regexp  正则
        PrefixQueryBuilder title = QueryBuilders.prefixQuery("title", "\\w+(.)*");

        searchSourceBuilder.query(title);
        searchRequest.source(searchSourceBuilder);
        SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        SearchHits searchHits = search.getHits();
        //获取记录数
        long value = searchHits.getTotalHits().value;
        log.info("value:{}", value);

        List<Goods> objects = new ArrayList<>();
        SearchHit[] hits = searchHits.getHits();
        for (SearchHit hit : hits) {
            String sourceAsString = hit.getSourceAsString();
            //转化为goods对象
            Goods goods = JSON.parseObject(sourceAsString, Goods.class);
            objects.add(goods);
        }
        log.info("objects :{}", objects);
        return objects;
    }


    /**
     * prefix查询:前缀查询
     *
     * @throws IOException
     */
    @GetMapping("prefixQuery")
    public List<Goods> prefixQuery() throws IOException {
        SearchRequest searchRequest = new SearchRequest("goods");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        // prefix查询:前缀查询
        PrefixQueryBuilder title = QueryBuilders.prefixQuery("brandName", "华");
        searchSourceBuilder.query(title);
        searchRequest.source(searchSourceBuilder);
        SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        SearchHits searchHits = search.getHits();
        //获取记录数
        long value = searchHits.getTotalHits().value;
        log.info("value:{}", value);

        List<Goods> objects = new ArrayList<>();
        SearchHit[] hits = searchHits.getHits();
        for (SearchHit hit : hits) {
            String sourceAsString = hit.getSourceAsString();
            //转化为goods对象
            Goods goods = JSON.parseObject(sourceAsString, Goods.class);
            objects.add(goods);
        }
        log.info("objects :{}", objects);
        return objects;
    }


    /**
     * prefix查询:前缀查询
     *
     * @throws IOException
     */
    @GetMapping("prefixquery")
    public List<Goods> prefixquery() throws IOException {
        SearchRequest searchRequest = new SearchRequest("goods");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        // prefix查询:前缀查询
        PrefixQueryBuilder title = QueryBuilders.prefixQuery("brandName", "华");
        searchSourceBuilder.query(title);
        searchRequest.source(searchSourceBuilder);
        SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        SearchHits searchHits = search.getHits();
        //获取记录数
        long value = searchHits.getTotalHits().value;
        log.info("value:{}", value);

        List<Goods> objects = new ArrayList<>();
        SearchHit[] hits = searchHits.getHits();
        for (SearchHit hit : hits) {
            String sourceAsString = hit.getSourceAsString();
            //转化为goods对象
            Goods goods = JSON.parseObject(sourceAsString, Goods.class);
            objects.add(goods);
        }
        log.info("objects :{}", objects);
        return objects;
    }


    /**
     * 范围查询:
     *
     * @throws IOException
     */
    @GetMapping("rangeQuery")
    public List<Goods> rangeQuery() throws IOException {
        SearchRequest searchRequest = new SearchRequest("goods");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        //指定需要查询的字段
        RangeQueryBuilder query = QueryBuilders.rangeQuery("price");
        //指定下限 	 gt 大于  gte大于等于
        query.gte(20);
//        指定上限 lt 小于 lte 小于等于
        query.lte(300);

        searchSourceBuilder.query(query);
        //排序
        searchSourceBuilder.sort("price", SortOrder.DESC);
        searchRequest.source(searchSourceBuilder);
        SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        SearchHits searchHits = search.getHits();
        //获取记录数
        long value = searchHits.getTotalHits().value;
        log.info("value:{}", value);

        List<Goods> objects = new ArrayList<>();
        SearchHit[] hits = searchHits.getHits();
        for (SearchHit hit : hits) {
            String sourceAsString = hit.getSourceAsString();
            //转化为goods对象
            Goods goods = JSON.parseObject(sourceAsString, Goods.class);
            objects.add(goods);
        }
        log.info("objects :{}", objects);
        return objects;
    }


    /**
     * queryString 查询
     *
     * @throws IOException
     */
    @GetMapping("queryStringQuery")
    public List<Goods> queryStringQuery() throws IOException {
        SearchRequest searchRequest = new SearchRequest("goods");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

//        queryString  查询 内容  华为手机 ;查询字段 title、categoryName
        QueryStringQueryBuilder queryStringQueryBuilder = QueryBuilders.queryStringQuery("华为手机").field("title").field("categoryName").defaultOperator(Operator.OR);

        searchSourceBuilder.query(queryStringQueryBuilder);
        searchRequest.source(searchSourceBuilder);
        SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        SearchHits searchHits = search.getHits();
        //获取记录数
        long value = searchHits.getTotalHits().value;
        log.info("value:{}", value);

        List<Goods> objects = new ArrayList<>();
        SearchHit[] hits = searchHits.getHits();
        for (SearchHit hit : hits) {
            String sourceAsString = hit.getSourceAsString();
            //转化为goods对象
            Goods goods = JSON.parseObject(sourceAsString, Goods.class);
            objects.add(goods);
        }
        log.info("objects :{}", objects);
        return objects;
    }


    /**
     * 布尔查询 boolquery
     * <p>
     * boolQuery:对多个查询条件连接。连接方式:
     * ●must (and) :条件必须成立
     * ●must not (not) :条件必须不成立
     * ●should (or) :条件可以成立
     * ●filter:条件必须成立,性能比must高。不会计算得分(得分=》_score)(搜索值与结果匹配,匹配度越高,的得分越高。得分越高的数据会排在前面)
     *
     * @throws IOException
     */
    @GetMapping("boolquery")
    public List<Goods> boolquery() throws IOException {
        SearchRequest searchRequest = new SearchRequest("goods");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        //1构建boolQuery
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();

        //2.1构建一个 termQuery 用于查询品牌
        TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("brandName", "华为");
        queryBuilder.must(termQueryBuilder);
        //2.2 标题包含手机
        MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("title", "手机");
        queryBuilder.filter(matchQueryBuilder);
        //2.3筛选价格
        RangeQueryBuilder priceQuery = QueryBuilders.rangeQuery("price");
        priceQuery.gte(20);
        priceQuery.lte(3000);
        queryBuilder.filter(priceQuery);

        //3使用bool连接
        searchSourceBuilder.query(queryBuilder);
        searchRequest.source(searchSourceBuilder);
        SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        SearchHits searchHits = search.getHits();
        //获取记录数
        long value = searchHits.getTotalHits().value;
        log.info("value:{}", value);

        List<Goods> objects = new ArrayList<>();
        SearchHit[] hits = searchHits.getHits();
        for (SearchHit hit : hits) {
            String sourceAsString = hit.getSourceAsString();
            //转化为goods对象
            Goods goods = JSON.parseObject(sourceAsString, Goods.class);
            objects.add(goods);
        }
        log.info("objects :{}", objects);
        return objects;
    }


    /**
     * 聚合查询1(桶聚合-group by)
     *
     * @throws IOException
     */
    @GetMapping("groupingQuery")
    public List<Goods> groupingQuery() throws IOException {
        SearchRequest searchRequest = new SearchRequest("goods");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        //筛选按title数据
        MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("title", "手机");
        searchSourceBuilder.query(matchQueryBuilder);

        //.terms("good_brands")自己起名 和 数据存储的变量名不能相同(数据库字段名不能相同)
        //.field("brandName") 需要分组的字段
        //.size(100) 展示100条
        AggregationBuilder agg = AggregationBuilders.terms("good_brands").field("brandName").size(100);
        searchSourceBuilder.aggregation(agg);

        searchRequest.source(searchSourceBuilder);
        SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        SearchHits searchHits = search.getHits();
        //获取记录数
        long value = searchHits.getTotalHits().value;
        log.info("value:{}", value);

        List<Goods> objects = new ArrayList<>();
        SearchHit[] hits = searchHits.getHits();
        for (SearchHit hit : hits) {
            String sourceAsString = hit.getSourceAsString();
            //转化为goods对象
            Goods goods = JSON.parseObject(sourceAsString, Goods.class);
            objects.add(goods);
        }
        log.info("objects :{}", objects);
        //获取聚合结果
        Aggregations aggregations = search.getAggregations();
        Map<String, Aggregation> aggMap = aggregations.asMap();


        Terms good_brands = (Terms) aggMap.get("good_brands");
        List<? extends Terms.Bucket> buckets = good_brands.getBuckets();

        List brands = new ArrayList<>();
        for (Terms.Bucket bucket : buckets) {
            Object key = bucket.getKey();
            log.info("key:{}", key);
            brands.add(key);
        }
        return objects;
    }

    /**
     * 聚合查询2 聚合查询
     *
     * @throws IOException
     */
    @GetMapping("functionQuery")
    public List<Goods> functionQuery() throws IOException {
        try {
            SearchRequest searchRequest = new SearchRequest("goods");
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

            //筛选按title数据
            MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("title", "手机");
            searchSourceBuilder.query(matchQueryBuilder);

            AggregationBuilder agg = AggregationBuilders.max("good_price").field("price");
            searchSourceBuilder.aggregation(agg);

            searchRequest.source(searchSourceBuilder);
            SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
            SearchHits searchHits = search.getHits();
            //获取记录数
            long value = searchHits.getTotalHits().value;
            log.info("value:{}", value);

            List<Goods> objects = new ArrayList<>();
            SearchHit[] hits = searchHits.getHits();
            for (SearchHit hit : hits) {
                String sourceAsString = hit.getSourceAsString();
                //转化为goods对象
                Goods goods = JSON.parseObject(sourceAsString, Goods.class);
                objects.add(goods);
            }
            log.info("objects :{}", objects);
            //获取聚合结果  其他聚合函数先写Parsed 然后根据代码提示写出相对应的结果
            ParsedMax aa = (ParsedMax) search.getAggregations().get("good_price");
            double value1 = aa.value();//获取max值
            return objects;
        } catch (IOException e) {
            log.error("e:{}", e);
            throw e;
        }
    }


    /**
     * 高亮查询
     * 高亮字段
     * 前缀
     * 后缀
     * <p>
     * 高亮数据替换原有数据
     *
     * @return
     * @throws IOException
     */
    @GetMapping("highlightQuery")
    public List<Goods> highlightQuery() throws IOException {
        try {
            SearchRequest searchRequest = new SearchRequest("goods");
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

            //筛选按title数据
            MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("title", "手机");
            searchSourceBuilder.query(matchQueryBuilder);

            AggregationBuilder agg = AggregationBuilders.max("good_price").field("price");
            searchSourceBuilder.aggregation(agg);

            //设置高亮
            HighlightBuilder highlightBuilder = new HighlightBuilder();
            //设置三要数
            highlightBuilder.field("title");
            highlightBuilder.preTags("<font color='red'>");
            highlightBuilder.postTags("</font>");
            searchSourceBuilder.highlighter(highlightBuilder);

            searchRequest.source(searchSourceBuilder);
            SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
            SearchHits searchHits = search.getHits();
            //获取记录数
            long value = searchHits.getTotalHits().value;
            log.info("value:{}", value);

            List<Goods> objects = new ArrayList<>();
            SearchHit[] hits = searchHits.getHits();
            for (SearchHit hit : hits) {
                String sourceAsString = hit.getSourceAsString();
                //转化为goods对象
                Goods goods = JSON.parseObject(sourceAsString, Goods.class);

                //获取高亮结果 提取goods中的title
                Map<String, HighlightField> highlightFields = hit.getHighlightFields();
                HighlightField highlightField = highlightFields.get("title");
                Text[] fragments = highlightField.getFragments();

                //替换
                goods.setTitle(fragments[0].toString());

                objects.add(goods);
            }
            log.info("objects :{}", objects);
            //获取聚合结果  其他聚合函数先写Parsed 然后根据代码提示写出相对应的结果
            ParsedMax aa = (ParsedMax) search.getAggregations().get("good_price");
            double value1 = aa.value();//获取max值
            return objects;
        } catch (IOException e) {
            log.error("e:{}", e);
            throw e;
        }
    }
    //endregion

 

import引用


import com.alibaba.fastjson.JSON;
import com.item.elasticsearch.domain.Goods;
import com.item.elasticsearch.domain.Person;
import com.item.elasticsearch.mapper.GoodsMapper;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
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.support.master.AcknowledgedResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.client.IndicesClient;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.client.indices.GetIndexResponse;
import org.elasticsearch.cluster.metadata.MappingMetadata;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.metrics.ParsedMax;
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.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

相关完整代码:

https://download.csdn.net/download/qq_36215047/19628216?spm=1001.2014.3001.5501

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值