ElasticSearch Java API之高级查询(分页查询,高亮查询,正则表达式查询,聚合查询等)

ElasticSearch 封装了很多查询方法

首先我们需要批量插入数据,以做测试使用

static void batchInsertDocument(RestHighLevelClient client) throws IOException {
    //创建批量新增请求对象
    BulkRequest request = new BulkRequest();
    request.add(new
            IndexRequest().index("userxt")
                    .id("1").source(XContentType.JSON,"name","xt","age","24")
            );
    request.add(new
            IndexRequest().index("userxt")
                    .id("2").source(XContentType.JSON, "name", "java","age","67")
            );
    request.add(new
            IndexRequest().index("userxt")
                    .id("3").source(XContentType.JSON, "name", "python","age","31")
            );
    request.add(new
            IndexRequest().index("userxt")
                    .id("4").source(XContentType.JSON, "name", "go","age","12")
            );
    //客户端发送请求,获取响应对象
    BulkResponse responses = client.bulk(request, RequestOptions.DEFAULT);
    //打印结果信息
    System.out.println("took:" + responses.getTook());
    System.out.println("items:" + responses.getItems());
}

查询所有文档数据

//查询所有文档数据
static void queryAllDocuments(RestHighLevelClient client,SearchRequest request) throws IOException {

    // 构建查询的请求体
    SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
    // 查询所有数据
    sourceBuilder.query(QueryBuilders.matchAllQuery());
    //发送请求,获得结果
    searchFunction(client,request,sourceBuilder);

}

条件查询

//条件查询
static void conditionQueryDocuments(RestHighLevelClient client,SearchRequest request) throws IOException {
    // 构建查询的请求体
    SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
    sourceBuilder.query(QueryBuilders.termQuery("age", "24"));

    //发送请求,获得结果
    searchFunction(client,request,sourceBuilder);
}

分页查询

// 分页查询
static void pagingQueryDocuments(RestHighLevelClient client,SearchRequest request) throws IOException {
    // 构建查询的请求体
    SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
    sourceBuilder.query(QueryBuilders.matchAllQuery());
    // 分页查询
    // 当前页其实索引(第一条数据的顺序号), from
    sourceBuilder.from(0);

    // 每页显示多少条 size  默认为10
    sourceBuilder.size(2);

    //发送请求,获得结果
    searchFunction(client,request,sourceBuilder);
}

对查询进行排序

// 对查询进行排序
static void orderingQueryDocuments(RestHighLevelClient client,SearchRequest request) throws IOException {

    // 构建查询的请求体
    SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
    sourceBuilder.query(QueryBuilders.matchAllQuery());
    // 排序
    sourceBuilder.sort("age", SortOrder.ASC);

    //发送请求,获得结果
    searchFunction(client,request,sourceBuilder);
}

bool查询(组合多条件查询)

// 组合多条件查询
static void combinationQueryDocuments(RestHighLevelClient client,SearchRequest request) throws IOException {

    // 构建查询的请求体
    SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
    BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
    // 必须包含
    boolQueryBuilder.must(QueryBuilders.matchQuery("age", "24"));
    // 一定不含
    boolQueryBuilder.mustNot(QueryBuilders.matchQuery("name", "go"));
    // 可能包含
    boolQueryBuilder.should(QueryBuilders.matchQuery("sex", "男"));
    sourceBuilder.query(boolQueryBuilder);
    
    //发送请求,获得结果
    searchFunction(client,request,sourceBuilder);
}

范围查询

//范围查询
static void rangeQueryDocuments(RestHighLevelClient client,SearchRequest request) throws IOException {
    // 构建查询的请求体
    SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
    RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery("age");
    // 大于等于  gt 大于
    rangeQuery.gte("20");
    // 小于等于 lt 小于
    rangeQuery.lte("50");
    sourceBuilder.query(rangeQuery);
    
    //发送请求,获得结果
    searchFunction(client,request,sourceBuilder);
}

模糊查询

//模糊查询  当用户输入有错误时,使用这个功能能在一定程度上召回一些和输入相近的文档。
static void fuzzyQueryDocuments(RestHighLevelClient client,SearchRequest request) throws IOException {

    // 构建查询的请求体
    SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
    //Damerau发现 80% 的人类拼写错误的编辑距离都是1. 换句话说, 80% 的拼写错误都可以通过 单次编辑修改为原始的字符串.
    sourceBuilder.query(QueryBuilders.fuzzyQuery("name","xt2").fuzziness(Fuzziness.ONE));
    //发送请求,获得结果
    searchFunction(client,request,sourceBuilder);
}

通配符查询

 //通配符查询 支持* 任意字符串;?任意一个字符
 static void wildcardQueryDocuments(RestHighLevelClient client,SearchRequest request){
     // 构建查询的请求体
     SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
     sourceBuilder.query(QueryBuilders.wildcardQuery("name","x*"));
     //发送请求,获得结果
     try {
         searchFunction(client,request,sourceBuilder);
     } catch (IOException e) {
         e.printStackTrace();
     }
 }

正则表达式查询

正则表达式规则:

  • ‘’."代表任意字符
  • "+"代表加号之前的最小单元匹配一次或多次
  • "*"代表星号之前的最小单元匹配零次或多次
  • "?"代表问号之前的最小单元匹配零次或一次
  • "{}"可以被用来声明之前的最小单元出现一个最少次数和最多次数 {2,5} 最少2次,最多5次
  • "()"被用来分组构成一个最小单元或者说是子模式 (ab)+ 代表ab匹配一次或多次
  • "|"可以作为一个或的操作符,符号左右侧的内容有一个匹配上就认为是匹配成功
  • "[]"作为一个选择符,意思是中括号内的任意字符出现都认为是匹配成功,加上^代表相反的意思,也就是说后的任意字符不出现都认为是匹配成功。
//正则表达式查询
static void regexpQueryDocuments(RestHighLevelClient client,SearchRequest request){
    // 构建查询的请求体
    SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
    //''."代表任意字符
    //"+"代表加号之前的最小单元匹配一次或多次
    //"*"代表星号之前的最小单元匹配零次或多次
    //"?"代表问号之前的最小单元匹配零次或一次
    //"{}"可以被用来声明之前的最小单元出现一个最少次数和最多次数 {2,5} 最少2次,最多5次
    //"()"被用来分组构成一个最小单元或者说是子模式  (ab)+ 代表ab匹配一次或多次
    //"|"可以作为一个或的操作符,符号左右侧的内容有一个匹配上就认为是匹配成功
    //"[]"作为一个选择符,意思是中括号内的任意字符出现都认为是匹配成功,加上^代表相反的意思,也就是说后的任意字符不出现都认为是匹配成功。
    sourceBuilder.query(QueryBuilders.regexpQuery("name","x.*"));
    //发送请求,获得结果
    try {
        searchFunction(client,request,sourceBuilder);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

高亮查询

// 高亮查询
static void highlightQueryDocuments(RestHighLevelClient client) throws IOException {
    SearchRequest request = new SearchRequest().indices("userxt");
    //2.创建查询请求体构建器
    SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
    //构建查询方式:高亮查询
    TermsQueryBuilder termsQueryBuilder =
            QueryBuilders.termsQuery("name","xt");
    //设置查询方式
    sourceBuilder.query(termsQueryBuilder);
    //构建高亮字段
    HighlightBuilder highlightBuilder = new HighlightBuilder();
    highlightBuilder.preTags("<font color='red'>");//设置标签前缀  可以自定义  默认为em 标签对
    highlightBuilder.postTags("</font>");//设置标签后缀
    highlightBuilder.field("name");//设置高亮字段
    //设置高亮构建对象
    sourceBuilder.highlighter(highlightBuilder);
    //设置请求体
    request.source(sourceBuilder);
    //3.客户端发送请求,获取响应对象
    SearchResponse response = client.search(request, RequestOptions.DEFAULT);
    //4.打印响应结果
    SearchHits hits = response.getHits();
    System.out.println("took:"+response.getTook());
    System.out.println("time_out:"+response.isTimedOut());
    System.out.println("total:"+hits.getTotalHits());
    System.out.println("max_score:"+hits.getMaxScore());
    System.out.println("--------------hits-------------");
    for (SearchHit hit : hits) {
        String sourceAsString = hit.getSourceAsString();
        System.out.println(sourceAsString);
        //打印高亮结果
        Map<String, HighlightField> highlightFields = hit.getHighlightFields();
        System.out.println(highlightFields);
    }
    System.out.println("--------------hits-------------");
}

聚合查询

//聚合查询
static void aggregateQueryDocuments(RestHighLevelClient client,SearchRequest request) throws IOException {

    SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
    sourceBuilder.aggregation(
            // 里面封装了很多 其他操作,可以自己修改
            AggregationBuilders.terms("age_groupby").field("age")
    );

    //发送请求,获得结果
    searchFunction(client,request,sourceBuilder);

}

如下图所示,封装了很多操作
在这里插入图片描述

完整代码

public class AdvancedOperation {

    public static void main(String[] args) throws IOException {

        final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
        credentialsProvider.setCredentials(AuthScope.ANY,
                new UsernamePasswordCredentials("xt", "xt"));


        RestClientBuilder restClientBuilder = RestClient.builder(
                new HttpHost("IP", 9200,"http"));

        // 认证和线程数
        restClientBuilder.setHttpClientConfigCallback(httpClientBuilder -> {
            httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
            int threadCount = 10;
            httpClientBuilder.setDefaultIOReactorConfig(IOReactorConfig.custom().setIoThreadCount(threadCount).build());

            return httpClientBuilder;
        });

        // 超时超时设置
        restClientBuilder.setRequestConfigCallback(requestConfigCallback -> {
            requestConfigCallback.setConnectTimeout(10000); //单位ms
            requestConfigCallback.setSocketTimeout(10000);
            return requestConfigCallback;
        });


        // 创建客户端对象   虽然已经被弃用,但是了解基本使用还是没有问题  里面封装了RestClient
        RestHighLevelClient client = new RestHighLevelClient(restClientBuilder);

        System.out.println(client);



        //批量插入数据
//        batchInsertDocument(client);


        // 创建搜索请求对象
        SearchRequest request = new SearchRequest();
        request.indices("userxt");


        //查询所有文档数据
        queryAllDocuments(client,request);
        //条件查询
        conditionQueryDocuments(client,request);
        //分页查询
        pagingQueryDocuments(client,request);
        // 对查询进行排序
        orderingQueryDocuments(client,request);
        // 组合多条件查询
        combinationQueryDocuments(client,request);
        //范围查询
        rangeQueryDocuments(client,request);
        //模糊查询
        fuzzyQueryDocuments(client,request);
        //通配符查询
        wildcardQueryDocuments(client,request);

        //正则表达式查询
        regexpQueryDocuments(client,request);

        //高亮查询
        highlightQueryDocuments(client,request);

        //聚合查询,有多种操作,min,max,avg,分组查询等等
        aggregateQueryDocuments(client,request);
    }


    static void batchInsertDocument(RestHighLevelClient client) throws IOException {
        //创建批量新增请求对象
        BulkRequest request = new BulkRequest();
        request.add(new
                IndexRequest().index("userxt")
                        .id("1").source(XContentType.JSON,"name","xt","age","24")
                );
        request.add(new
                IndexRequest().index("userxt")
                        .id("2").source(XContentType.JSON, "name", "java","age","67")
                );
        request.add(new
                IndexRequest().index("userxt")
                        .id("3").source(XContentType.JSON, "name", "python","age","31")
                );
        request.add(new
                IndexRequest().index("userxt")
                        .id("4").source(XContentType.JSON, "name", "go","age","12")
                );
        //客户端发送请求,获取响应对象
        BulkResponse responses = client.bulk(request, RequestOptions.DEFAULT);
        //打印结果信息
        System.out.println("took:" + responses.getTook());
        System.out.println("items:" + responses.getItems());
    }



    //查询所有文档数据
    static void queryAllDocuments(RestHighLevelClient client,SearchRequest request) throws IOException {

        // 构建查询的请求体
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        // 查询所有数据
        sourceBuilder.query(QueryBuilders.matchAllQuery());
        //发送请求,获得结果
        searchFunction(client,request,sourceBuilder);

    }

    //条件查询
    static void conditionQueryDocuments(RestHighLevelClient client,SearchRequest request) throws IOException {
        // 构建查询的请求体
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(QueryBuilders.termQuery("age", "24"));

        //发送请求,获得结果
        searchFunction(client,request,sourceBuilder);
    }

    // 分页查询
    static void pagingQueryDocuments(RestHighLevelClient client,SearchRequest request) throws IOException {
        // 构建查询的请求体
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(QueryBuilders.matchAllQuery());
        // 分页查询
        // 当前页其实索引(第一条数据的顺序号), from
        sourceBuilder.from(0);

        // 每页显示多少条 size  默认为10
        sourceBuilder.size(2);

        //发送请求,获得结果
        searchFunction(client,request,sourceBuilder);
    }

    // 对查询进行排序
    static void orderingQueryDocuments(RestHighLevelClient client,SearchRequest request) throws IOException {

        // 构建查询的请求体
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(QueryBuilders.matchAllQuery());
        // 排序
        sourceBuilder.sort("age", SortOrder.ASC);

        //发送请求,获得结果
        searchFunction(client,request,sourceBuilder);
    }

    // 组合多条件查询
    static void combinationQueryDocuments(RestHighLevelClient client,SearchRequest request) throws IOException {

        // 构建查询的请求体
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        // 必须包含
        boolQueryBuilder.must(QueryBuilders.matchQuery("age", "24"));
        // 一定不含
        boolQueryBuilder.mustNot(QueryBuilders.matchQuery("name", "go"));
        // 可能包含
        boolQueryBuilder.should(QueryBuilders.matchQuery("sex", "男"));
        sourceBuilder.query(boolQueryBuilder);

        //发送请求,获得结果
        searchFunction(client,request,sourceBuilder);
    }

    //范围查询
    static void rangeQueryDocuments(RestHighLevelClient client,SearchRequest request) throws IOException {
        // 构建查询的请求体
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery("age");
        // 大于等于  gt 大于
        rangeQuery.gte("20");
        // 小于等于 lt 小于
        rangeQuery.lte("50");
        sourceBuilder.query(rangeQuery);

        //发送请求,获得结果
        searchFunction(client,request,sourceBuilder);
    }

    //模糊查询  当用户输入有错误时,使用这个功能能在一定程度上召回一些和输入相近的文档。
    static void fuzzyQueryDocuments(RestHighLevelClient client,SearchRequest request) throws IOException {

        // 构建查询的请求体
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //Damerau发现 80% 的人类拼写错误的编辑距离都是1. 换句话说, 80% 的拼写错误都可以通过 单次编辑修改为原始的字符串.
        sourceBuilder.query(QueryBuilders.fuzzyQuery("name","xt2").fuzziness(Fuzziness.ONE));
        //发送请求,获得结果
        searchFunction(client,request,sourceBuilder);
    }

    //通配符查询 支持* 任意字符串;?任意一个字符
    static void wildcardQueryDocuments(RestHighLevelClient client,SearchRequest request){
        // 构建查询的请求体
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(QueryBuilders.wildcardQuery("name","x*"));
        //发送请求,获得结果
        try {
            searchFunction(client,request,sourceBuilder);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    //正则表达式查询
    static void regexpQueryDocuments(RestHighLevelClient client,SearchRequest request){
        // 构建查询的请求体
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //''."代表任意字符
        //"+"代表加号之前的最小单元匹配一次或多次
        //"*"代表星号之前的最小单元匹配零次或多次
        //"?"代表问号之前的最小单元匹配零次或一次
        //"{}"可以被用来声明之前的最小单元出现一个最少次数和最多次数 {2,5} 最少2次,最多5次
        //"()"被用来分组构成一个最小单元或者说是子模式  (ab)+ 代表ab匹配一次或多次
        //"|"可以作为一个或的操作符,符号左右侧的内容有一个匹配上就认为是匹配成功
        //"[]"作为一个选择符,意思是中括号内的任意字符出现都认为是匹配成功,加上^代表相反的意思,也就是说后的任意字符不出现都认为是匹配成功。
        sourceBuilder.query(QueryBuilders.regexpQuery("name","x.*"));
        //发送请求,获得结果
        try {
            searchFunction(client,request,sourceBuilder);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 高亮查询
    static void highlightQueryDocuments(RestHighLevelClient client,SearchRequest request) throws IOException {

        //2.创建查询请求体构建器
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //构建查询方式:高亮查询
        TermsQueryBuilder termsQueryBuilder =
                QueryBuilders.termsQuery("name","xt");
        //设置查询方式
        sourceBuilder.query(termsQueryBuilder);
        //构建高亮字段
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.preTags("<font color='red'>");//设置标签前缀  可以自定义  默认为em 标签对
        highlightBuilder.postTags("</font>");//设置标签后缀
        highlightBuilder.field("name");//设置高亮字段
        //设置高亮构建对象
        sourceBuilder.highlighter(highlightBuilder);


        //设置请求体
        request.source(sourceBuilder);
        //3.客户端发送请求,获取响应对象
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        //4.打印响应结果
        SearchHits hits = response.getHits();
        System.out.println("took:"+response.getTook());
        System.out.println("time_out:"+response.isTimedOut());
        System.out.println("total:"+hits.getTotalHits());
        System.out.println("max_score:"+hits.getMaxScore());
        System.out.println("--------------hits-------------");
        for (SearchHit hit : hits) {
            String sourceAsString = hit.getSourceAsString();
            System.out.println(sourceAsString);
            //打印高亮结果
            Map<String, HighlightField> highlightFields = hit.getHighlightFields();
            System.out.println(highlightFields);
        }
        System.out.println("--------------hits-------------");
    }

    //聚合查询
    static void aggregateQueryDocuments(RestHighLevelClient client,SearchRequest request) throws IOException {

        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.aggregation(
                // 里面封装了很多 其他操作,可以自己修改
                AggregationBuilders.terms("age_groupby").field("age")
        );

        //发送请求,获得结果
        searchFunction(client,request,sourceBuilder);

    }



    private static void searchFunction(RestHighLevelClient client,SearchRequest request,SearchSourceBuilder sourceBuilder) throws IOException {
        //设置请求体
        request.source(sourceBuilder);
        //客户端发送请求,获取响应对象
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        // 打印响应结果
        SearchHits hits = response.getHits();
        System.out.println("took:" + response.getTook());
        System.out.println("timeout:" + response.isTimedOut());
        System.out.println("total:" + hits.getTotalHits());
        System.out.println("MaxScore:" + hits.getMaxScore());
        System.out.println("--------------hits-------------");
        for (SearchHit hit : hits) {
            //输出每条查询的结果信息
            System.out.println(hit.getSourceAsString());
        }
        System.out.println("---------------hits-------------");
    }
}

References:

  • https://www.jianshu.com/p/a85b60e86d7b
  • https://www.bilibili.com/video/BV1hh411D7sb?p=25
  • https://www.cnblogs.com/chenyuanbo/p/10296845.html
  • https://www.jianshu.com/p/c2767e980368

(写博客主要是对自己学习的归纳整理,资料大部分来源于书籍、网络资料、官方文档和自己的实践,整理的不足和错误之处,请大家评论区批评指正。同时感谢广大博主和广大作者辛苦整理出来的资源和分享的知识。)

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
可以使用 Elasticsearch Java API 中的 Aggregation API 来实现聚合查询某一字段分组的数量。具体步骤如下: 1. 创建一个 SearchRequest 对象,并设置索引及查询条件: ``` SearchRequest searchRequest = new SearchRequest("index_name"); SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); searchSourceBuilder.query(QueryBuilders.matchAllQuery()); ``` 2. 创建一个 TermsAggregationBuilder 对象,并设置聚合字段: ``` TermsAggregationBuilder aggregationBuilder = AggregationBuilders.terms("group_by_field") .field("field_name") .size(10); // 设置返回结果的数量 ``` 3. 将聚合对象添加到 SearchSourceBuilder 中: ``` searchSourceBuilder.aggregation(aggregationBuilder); ``` 4. 执行查询,并处理返回结果: ``` searchRequest.source(searchSourceBuilder); SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT); Terms termsAggregation = response.getAggregations().get("group_by_field"); for (Terms.Bucket bucket : termsAggregation.getBuckets()) { String key = bucket.getKeyAsString(); long count = bucket.getDocCount(); System.out.println("Key: " + key + ", Count: " + count); } ``` 以上代码中,`client` 是一个 Elasticsearch 客户端对象,通过 `response.getAggregations().get("group_by_field")` 获取到聚合结果对象,然后遍历 Buckets 获取每个分组的 key 和 count。 需要注意的是,这里使用的是 TermsAggregationBuilder 对象来实现分组聚合查询,如果需要根据其他条件进行聚合查询,则需要使用其他类型的 AggregationBuilder 对象。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值