ElasticSearch全文搜索引擎之查询API操作详解

目录

一、简介

二、查询API详解

三、总结


一、简介

前面一篇文章已经总结一些索引和文档相关的操作API,本篇文章将介绍Java客户端中如何查询搜索引擎中的数据,同样查询API也是基于RestHighLevelClient实现。

二、查询API详解

es查询API使用大体步骤:

  1. 构造SearchRequest查询请求对象,支持设置超时时间等信息;创建SeachRequest,如果没有传参数,这将针对所有索引运行。如果传了有参数,则按参数所传值为索引,此处“student_info”为索引库名称,大多数搜索参数都添加到SearchSourceBuilder中,它为搜索请求body中的所有内容提供了setter;
  2. 构造QueryBuilder对象,常见的QueryBuilder有BoolQueryBuilder、MatchQueryBuilder、RangeQueryBuilder等;
  3. 构造SearchSourceBuilder对象,调用searchSourceBuilder.query(xxxQueryBuilder)方法; //设置查询,可以是任何类型的QueryBuilder。
  4. 调用searchRequest.source(searchSourceBuilder)方法; //将SearchSourceBuilder添加到SeachRequest。
  5. 执行查询请求,restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
  6. 获取响应结果并解析;

RestHighLevelClient查询ES中数据的API主要有:must、match_all、match、should、range、order等等。

search查询的主要参数是SearchRequest,我们的查询条件index、type、字段、字段值 都封装在SearchRequest中;

而index、type是直接封装在SearchRequest的对象中,查询的字段、字段值、查询方式则封装在SearchRequest中的对象属性SearchSourceBuilder中;

下面通过几个常见的查询示例说明如何通过RestHighLevelClient查询es索引中数据。

【a】match_all全部匹配搜索

  • QueryBuilders.matchAllQuery()
/**
     * match_all全部匹配搜索: QueryBuilders.matchAllQuery()
     */
    @Test
    void matchAllSearch() throws IOException {
        SearchRequest searchRequest = new SearchRequest("student_info");
        //构建搜索条件
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //全部匹配查询
        MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();
        searchSourceBuilder.query(matchAllQueryBuilder);
        //设置超时时间
        searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
        searchRequest.source(searchSourceBuilder);
        SearchResponse response = null;
        try {
            //执行查询请求,获取响应结果
            response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //循环遍历查询结果
        System.out.println(JSON.toJSONString(response.getHits()));
        for (SearchHit documentFields : response.getHits().getHits()) {
            System.out.println(documentFields.getSourceAsMap());
        }
        restHighLevelClient.close();
    }

控制台日志如下: 

{"fragment":true,"hits":[{"fields":{},"fragment":false,"highlightFields":{},"id":"1","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":1.0,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"张三","age":10},"sourceAsString":"{\"age\":10,\"name\":\"张三\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1},{"fields":{},"fragment":false,"highlightFields":{},"id":"2","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":1.0,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"李四","age":20},"sourceAsString":"{\"age\":20,\"name\":\"李四\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1},{"fields":{},"fragment":false,"highlightFields":{},"id":"3","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":1.0,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"王五","age":30},"sourceAsString":"{\"age\":30,\"name\":\"王五\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1},{"fields":{},"fragment":false,"highlightFields":{},"id":"4","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":1.0,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"赵六","age":40},"sourceAsString":"{\"age\":40,\"name\":\"赵六\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1},{"fields":{},"fragment":false,"highlightFields":{},"id":"5","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":1.0,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"田七","age":50},"sourceAsString":"{\"age\":50,\"name\":\"田七\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1}],"maxScore":1.0,"totalHits":{"relation":"EQUAL_TO","value":5}}
{name=张三, age=10}
{name=李四, age=20}
{name=王五, age=30}
{name=赵六, age=40}
{name=田七, age=50}

【b】只返回特定字段

  • searchSourceBuilder.fetchSource("name", "age")

通常使用下面两种方法(任意一种)设置查询返回的字段集合,方法还接受一个或多个通配符模式的数组,以控制以更精细的方式包含或排除哪些字段。第一个是获取的字段,第二个是过滤的字段,默认获取全部。

public SearchSourceBuilder fetchSource(@Nullable String include, @Nullable String exclude) {
        return this.fetchSource(include == null ? Strings.EMPTY_ARRAY : new String[]{include}, exclude == null ? Strings.EMPTY_ARRAY : new String[]{exclude});
    }

    public SearchSourceBuilder fetchSource(@Nullable String[] includes, @Nullable String[] excludes) {
        FetchSourceContext fetchSourceContext = this.fetchSourceContext != null ? this.fetchSourceContext : FetchSourceContext.FETCH_SOURCE;
        this.fetchSourceContext = new FetchSourceContext(fetchSourceContext.fetchSource(), includes, excludes);
        return this;
    }
/**
     * 只返回特定字段: searchSourceBuilder.fetchSource("name", "age")
     */
    @Test
    void notAllFieldsSearch() throws IOException {
        SearchRequest searchRequest = new SearchRequest("student_info");
        //构建搜索条件
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //全部匹配查询
        MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();
        searchSourceBuilder.query(matchAllQueryBuilder);
        //设置超时时间
        searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
        //只返回name字段,排除age字段
        searchSourceBuilder.fetchSource("name", "age");
        searchRequest.source(searchSourceBuilder);
        SearchResponse response = null;
        try {
            //执行查询请求,获取响应结果
            response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //循环遍历查询结果
        System.out.println(JSON.toJSONString(response.getHits()));
        for (SearchHit documentFields : response.getHits().getHits()) {
            System.out.println(documentFields.getSourceAsMap());
        }
        restHighLevelClient.close();
    }

控制台日志如下:

{"fragment":true,"hits":[{"fields":{},"fragment":false,"highlightFields":{},"id":"1","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":1.0,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"张三"},"sourceAsString":"{\"name\":\"张三\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1},{"fields":{},"fragment":false,"highlightFields":{},"id":"2","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":1.0,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"李四"},"sourceAsString":"{\"name\":\"李四\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1},{"fields":{},"fragment":false,"highlightFields":{},"id":"3","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":1.0,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"王五"},"sourceAsString":"{\"name\":\"王五\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1},{"fields":{},"fragment":false,"highlightFields":{},"id":"4","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":1.0,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"赵六"},"sourceAsString":"{\"name\":\"赵六\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1},{"fields":{},"fragment":false,"highlightFields":{},"id":"5","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":1.0,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"田七"},"sourceAsString":"{\"name\":\"田七\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1}],"maxScore":1.0,"totalHits":{"relation":"EQUAL_TO","value":5}}
{name=张三}
{name=李四}
{name=王五}
{name=赵六}
{name=田七}

【c】match模糊搜索

  • QueryBuilders.matchQuery("name", "张")
/**
     * match模糊搜索: QueryBuilders.matchQuery("name", "张")
     * 查询name字段中包含"张"的记录
     */
    @Test
    void matchSearch() throws IOException {
        SearchRequest searchRequest = new SearchRequest("student_info");
        //构建搜索条件
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //查询name字段中包含"张"的记录
        MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("name", "张");
        searchSourceBuilder.query(matchQueryBuilder);
        //设置超时时间
        searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
        searchRequest.source(searchSourceBuilder);
        SearchResponse response = null;
        try {
            //执行查询请求,获取响应结果
            response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //循环遍历查询结果
        System.out.println(JSON.toJSONString(response.getHits()));
        for (SearchHit documentFields : response.getHits().getHits()) {
            System.out.println(documentFields.getSourceAsMap());
        }
        restHighLevelClient.close();
    }

控制台日志如下:

{"fragment":true,"hits":[{"fields":{},"fragment":false,"highlightFields":{},"id":"1","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":1.3862942,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"张三","age":10},"sourceAsString":"{\"age\":10,\"name\":\"张三\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1}],"maxScore":1.3862942,"totalHits":{"relation":"EQUAL_TO","value":1}}
{name=张三, age=10}

【d】term精确搜索

  • QueryBuilders.termQuery("name", "张")
/**
     * term精确搜索
     */
    @Test
    void termSearch() throws IOException {
        SearchRequest searchRequest = new SearchRequest("student_info");
        //构建搜索条件
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //精确查询  name精确匹配"张"的记录
        TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name", "张");
        searchSourceBuilder.query(termQueryBuilder);
        //设置超时时间
        searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
        searchRequest.source(searchSourceBuilder);
        SearchResponse response = null;
        try {
            //执行查询请求,获取响应结果
            response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //循环遍历查询结果
        System.out.println(JSON.toJSONString(response.getHits()));
        for (SearchHit documentFields : response.getHits().getHits()) {
            System.out.println(documentFields.getSourceAsMap());
        }
        restHighLevelClient.close();
    }

控制台日志如下:

{"fragment":true,"hits":[{"fields":{},"fragment":false,"highlightFields":{},"id":"1","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":1.3862942,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"张三","age":10},"sourceAsString":"{\"age\":10,\"name\":\"张三\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1}],"maxScore":1.3862942,"totalHits":{"relation":"EQUAL_TO","value":1}}
{name=张三, age=10}

【e】范围查询

  • QueryBuilders.rangeQuery("age")
/**
     * 范围查询
     */
    @Test
    void rangeSearch() throws IOException {
        SearchRequest searchRequest = new SearchRequest("student_info");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //构建bool查询
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        //年龄大于等于20,小于等于40的记录
        boolQueryBuilder.must(
                QueryBuilders.rangeQuery("age")  //指定范围查询的字段
                        .gte("20")
                        .lte("50")
        );
        searchSourceBuilder.query(boolQueryBuilder);
        searchRequest.source(searchSourceBuilder);
        SearchResponse response = null;
        try {
            response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //循环遍历查询结果
        System.out.println(JSON.toJSONString(response.getHits()));
        for (SearchHit documentFields : response.getHits().getHits()) {
            System.out.println(documentFields.getSourceAsMap());
        }
        restHighLevelClient.close();
    }

控制台日志如下:

{"fragment":true,"hits":[{"fields":{},"fragment":false,"highlightFields":{},"id":"2","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":1.0,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"李四","age":20},"sourceAsString":"{\"age\":20,\"name\":\"李四\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1},{"fields":{},"fragment":false,"highlightFields":{},"id":"3","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":1.0,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"王五","age":30},"sourceAsString":"{\"age\":30,\"name\":\"王五\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1},{"fields":{},"fragment":false,"highlightFields":{},"id":"4","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":1.0,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"赵六","age":40},"sourceAsString":"{\"age\":40,\"name\":\"赵六\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1},{"fields":{},"fragment":false,"highlightFields":{},"id":"5","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":1.0,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"田七","age":50},"sourceAsString":"{\"age\":50,\"name\":\"田七\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1}],"maxScore":1.0,"totalHits":{"relation":"EQUAL_TO","value":4}}
{name=李四, age=20}
{name=王五, age=30}
{name=赵六, age=40}
{name=田七, age=50}

【f】must与查询(相当于and)

  • must表示符合条件的,相反的mustnot表示不符合条件的。
/**
     * must与查询(相当于and)
     */
    @Test
    void mustQuery() {
        //构造查询请求
        SearchRequest searchRequest = new SearchRequest("student_info");
        //构造SearchSourceBuilder
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //构造bool查询
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

        /**
         * must: and且查询
         * select * from xxx where name (like '%张%' ) and (age >= 10 and age <= 20)
         */

        //1.范围查询: 年龄大于等于10、小于等于20的记录
        RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("age");
        rangeQueryBuilder.lte(20).gte(10);
        boolQueryBuilder.must(rangeQueryBuilder);

        //2.match匹配查询: 姓名中包含"张"的记录
        MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("name", "张");
        boolQueryBuilder.must(matchQueryBuilder);

        searchSourceBuilder.query(boolQueryBuilder);
        searchRequest.source(searchSourceBuilder);
        SearchResponse response = null;
        try {
            //执行请求,返回响应结果
            response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println(JSON.toJSONString(response.getHits()));
        for (SearchHit searchHit : response.getHits().getHits()) {
            System.out.println(searchHit.getSourceAsMap());
        }
    }

控制台日志如下:

{"fragment":true,"hits":[{"fields":{},"fragment":false,"highlightFields":{},"id":"1","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":2.3862944,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"张三","age":10},"sourceAsString":"{\"age\":10,\"name\":\"张三\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1}],"maxScore":2.3862944,"totalHits":{"relation":"EQUAL_TO","value":1}}
{name=张三, age=10}

【g】should或查询(相当于or)

/**
     * should或查询(相当于or)
     */
    @Test
    void shouldQuery() {
        //构造查询请求
        SearchRequest searchRequest = new SearchRequest("student_info");
        //构造SearchSourceBuilder
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        //构造bool查询
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

        /**
         * should: or或查询
         * select * from xxx where name (like '%张%' ) or (age >= 10 and age <= 20)
         */

        //1.范围查询: 年龄大于等于10、小于等于20的记录
        RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("age");
        rangeQueryBuilder.lte(20).gte(10);
        boolQueryBuilder.should(rangeQueryBuilder);

        //2.match匹配查询: 姓名中包含"张"的记录
        MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("name", "张");
        boolQueryBuilder.should(matchQueryBuilder);

        searchSourceBuilder.query(boolQueryBuilder);
        searchRequest.source(searchSourceBuilder);
        SearchResponse response = null;
        try {
            //执行请求,返回响应结果
            response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println(JSON.toJSONString(response.getHits()));
        for (SearchHit searchHit : response.getHits().getHits()) {
            System.out.println(searchHit.getSourceAsMap());
        }
    }

控制台日志如下:

{"fragment":true,"hits":[{"fields":{},"fragment":false,"highlightFields":{},"id":"1","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":2.3862944,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"张三","age":10},"sourceAsString":"{\"age\":10,\"name\":\"张三\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1},{"fields":{},"fragment":false,"highlightFields":{},"id":"2","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":1.0,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"李四","age":20},"sourceAsString":"{\"age\":20,\"name\":\"李四\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1}],"maxScore":2.3862944,"totalHits":{"relation":"EQUAL_TO","value":2}}
{name=张三, age=10}
{name=李四, age=20}

【h】带排序的搜索

SearchSourceBuilder的排序:允许添加一个或多个SortBuilder实例,有四种特殊的实现(Field-,Score-,GeoDistance-和ScriptSortBuilder)。

  1. sourceBuilder.sort(new ScoreSortBuilder().order(SortOrder.DESC));    //按_score降序排序(默认值) 
  2. sourceBuilder.sort(new FieldSortBuilder("_id").order(SortOrder.ASC));    //按_id字段进行升序排序
  • searchSourceBuilder.sort("age", SortOrder.DESC);
/**
     * 带排序的搜索: searchSourceBuilder.sort("age", SortOrder.DESC);
     */
    @Test
    void sortQuery() throws IOException {
        SearchRequest searchRequest = new SearchRequest("student_info");
        //构建搜索条件
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();
        searchSourceBuilder.query(matchAllQueryBuilder);
        //设置超时时间
        searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
        //按age降序排序
        searchSourceBuilder.sort("age", SortOrder.DESC);
        searchRequest.source(searchSourceBuilder);
        SearchResponse response = null;
        try {
            //执行查询请求,获取响应结果
            response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //循环遍历查询结果
        System.out.println(JSON.toJSONString(response.getHits()));
        for (SearchHit documentFields : response.getHits().getHits()) {
            System.out.println(documentFields.getSourceAsMap());
        }
        restHighLevelClient.close();
    }

控制台日志如下:

{"fragment":true,"hits":[{"fields":{},"fragment":false,"highlightFields":{},"id":"5","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":null,"seqNo":-2,"sortValues":[50],"sourceAsMap":{"name":"田七","age":50},"sourceAsString":"{\"age\":50,\"name\":\"田七\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1},{"fields":{},"fragment":false,"highlightFields":{},"id":"4","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":null,"seqNo":-2,"sortValues":[40],"sourceAsMap":{"name":"赵六","age":40},"sourceAsString":"{\"age\":40,\"name\":\"赵六\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1},{"fields":{},"fragment":false,"highlightFields":{},"id":"3","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":null,"seqNo":-2,"sortValues":[30],"sourceAsMap":{"name":"王五","age":30},"sourceAsString":"{\"age\":30,\"name\":\"王五\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1},{"fields":{},"fragment":false,"highlightFields":{},"id":"2","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":null,"seqNo":-2,"sortValues":[20],"sourceAsMap":{"name":"李四","age":20},"sourceAsString":"{\"age\":20,\"name\":\"李四\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1},{"fields":{},"fragment":false,"highlightFields":{},"id":"1","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":null,"seqNo":-2,"sortValues":[10],"sourceAsMap":{"name":"张三","age":10},"sourceAsString":"{\"age\":10,\"name\":\"张三\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1}],"maxScore":null,"totalHits":{"relation":"EQUAL_TO","value":5}}
{name=田七, age=50}
{name=赵六, age=40}
{name=王五, age=30}
{name=李四, age=20}
{name=张三, age=10}

【i】分页搜索

  • searchSourceBuilder.from(1);    //设置确定结果要从哪个索引开始搜索的from选项,默认为0
  • searchSourceBuilder.size(2);    //设置确定搜素命中返回数的size选项,默认为10
/**
     * 分页搜索: searchSourceBuilder.from(1);  searchSourceBuilder.size(2);
     */
    @Test
    void paginationQuery() throws IOException {
        SearchRequest searchRequest = new SearchRequest("student_info");
        //构建搜索条件
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        MatchAllQueryBuilder matchAllQueryBuilder = QueryBuilders.matchAllQuery();
        searchSourceBuilder.query(matchAllQueryBuilder);
        //设置超时时间
        searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
        //按age降序排序
        searchSourceBuilder.sort("age", SortOrder.DESC);
        //从第一条记录开始,每页展示两条
        searchSourceBuilder.from(1);
        searchSourceBuilder.size(2);
        searchRequest.source(searchSourceBuilder);
        SearchResponse response = null;
        try {
            //执行查询请求,获取响应结果
            response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //循环遍历查询结果
        System.out.println(JSON.toJSONString(response.getHits()));
        for (SearchHit documentFields : response.getHits().getHits()) {
            System.out.println(documentFields.getSourceAsMap());
        }
        restHighLevelClient.close();
    }

控制台日志如下:

{"fragment":true,"hits":[{"fields":{},"fragment":false,"highlightFields":{},"id":"4","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":null,"seqNo":-2,"sortValues":[40],"sourceAsMap":{"name":"赵六","age":40},"sourceAsString":"{\"age\":40,\"name\":\"赵六\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1},{"fields":{},"fragment":false,"highlightFields":{},"id":"3","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":null,"seqNo":-2,"sortValues":[30],"sourceAsMap":{"name":"王五","age":30},"sourceAsString":"{\"age\":30,\"name\":\"王五\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1}],"maxScore":null,"totalHits":{"relation":"EQUAL_TO","value":5}}
{name=赵六, age=40}
{name=王五, age=30}

【j】高亮搜索

通过在SearchSourceBuilder上设置HighlightBuilder,可以实现高亮搜索结果。

  • HighlightBuilder highlightBuilder = new HighlightBuilder();
  • highlightBuilder.field("name"); 
  • highlightBuilder.preTags("<span style=\"color:red\">");
  • highlightBuilder.postTags("</span>");
  • searchSourceBuilder.highlighter(highlightBuilder);
/**
     * 高亮显示搜索
     */
    @Test
    void highLightQuery() throws IOException {
        SearchRequest searchRequest = new SearchRequest("student_info");
        //构建搜索条件
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("name", "张");
        //设置超时时间
        searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
        //按age降序排序
        searchSourceBuilder.sort("age", SortOrder.DESC);
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        //指定高亮字段
        highlightBuilder.field("name");
        //指定前置标签
        highlightBuilder.preTags("<span style=\"color:red\">");
        //指定后置标签
        highlightBuilder.postTags("</span>");
        searchSourceBuilder.highlighter(highlightBuilder);
        searchSourceBuilder.query(matchQueryBuilder);
        searchRequest.source(searchSourceBuilder);
        SearchResponse response = null;
        try {
            //执行查询请求,获取响应结果
            response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //循环遍历查询结果
        System.out.println(JSON.toJSONString(response.getHits()));
        for (SearchHit searchHit : response.getHits().getHits()) {
            Map<String, Object> sourceAsMap = searchHit.getSourceAsMap();
            //获取对应的高亮域
            Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
            //获取高亮字段
            HighlightField name = highlightFields.get("name");
            if (null != name) {
                // 为name串值增加自定义的高亮标签
                Text[] nameTexts = name.fragments();
                StringBuilder newName = new StringBuilder();
                for (Text text : nameTexts) {
                    newName.append(text);
                }
                //将追加了高亮标签的串值重新填充到对应的对象
                sourceAsMap.put("name", newName.toString());
            }
            System.out.println(sourceAsMap);
        }
        restHighLevelClient.close();
    }

控制台日志输出:

{"fragment":true,"hits":[{"fields":{},"fragment":false,"highlightFields":{"name":{"fragment":true,"fragments":[{"fragment":true}],"name":"name"}},"id":"1","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":null,"seqNo":-2,"sortValues":[10],"sourceAsMap":{"name":"张三","age":10},"sourceAsString":"{\"age\":10,\"name\":\"张三\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1}],"maxScore":null,"totalHits":{"relation":"EQUAL_TO","value":1}}
{name=<span style="color:red">张</span>三, age=10}

【k】一次查询多个条件

  • MultiSearchRequest multiSearchRequest = new MultiSearchRequest();
  • restHighLevelClient.msearch(multiSearchRequest, RequestOptions.DEFAULT)
  /**
     * 一次查询多个条件: restHighLevelClient.msearch(multiSearchRequest, RequestOptions.DEFAULT)
     */
    @Test
    void multiSearchQuery() throws IOException {
        //构造请求MultiSearchRequest
        MultiSearchRequest multiSearchRequest = new MultiSearchRequest();
        /*
         * 第一个SearchRequest
         */
        SearchRequest firstSearchRequest = new SearchRequest("student_info");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("name", "张");
        searchSourceBuilder.query(matchQueryBuilder);
        firstSearchRequest.source(searchSourceBuilder);
        multiSearchRequest.add(firstSearchRequest);
        /*
         * 第二个SearchRequest
         */
        SearchRequest secondSearchRequest = new SearchRequest("student_info");
        searchSourceBuilder = new SearchSourceBuilder();
        matchQueryBuilder = QueryBuilders.matchQuery("name", "李");
        searchSourceBuilder.query(matchQueryBuilder);
        secondSearchRequest.source(searchSourceBuilder);
        multiSearchRequest.add(secondSearchRequest);

        MultiSearchResponse multiSearchResponse;
        try {
            //执行请求,返回多个响应
            multiSearchResponse = restHighLevelClient.msearch(multiSearchRequest, RequestOptions.DEFAULT);
            multiSearchResponse.forEach(t -> {
                SearchResponse response = t.getResponse();
                //循环遍历查询结果
                System.out.println(JSON.toJSONString(response.getHits()));
                for (SearchHit searchHit : response.getHits().getHits()) {
                    System.out.println(searchHit.getSourceAsMap());
                }
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
        restHighLevelClient.close();
    }

 控制台日志输出:

{"fragment":true,"hits":[{"fields":{},"fragment":false,"highlightFields":{},"id":"1","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":1.3862942,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"张三","age":10},"sourceAsString":"{\"age\":10,\"name\":\"张三\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1}],"maxScore":1.3862942,"totalHits":{"relation":"EQUAL_TO","value":1}}
{name=张三, age=10}
{"fragment":true,"hits":[{"fields":{},"fragment":false,"highlightFields":{},"id":"2","matchedQueries":[],"primaryTerm":0,"rawSortValues":[],"score":1.3862942,"seqNo":-2,"sortValues":[],"sourceAsMap":{"name":"李四","age":20},"sourceAsString":"{\"age\":20,\"name\":\"李四\"}","sourceRef":{"fragment":true},"type":"_doc","version":-1}],"maxScore":1.3862942,"totalHits":{"relation":"EQUAL_TO","value":1}}
{name=李四, age=20}

三、总结

以上总结了一些常见的ES Java客户端查询API相关的示例,在实际项目中,得根据具体的业务需求,灵活构造不同的xxxQueryBuilder实现。希望以上代码可以帮助到读者,也能为以后再次使用时提供帮助。由于笔者水平有限,以上如有不对之处,还望指正,相互学习,一起进步!

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值