jjzjj

【ElasticSearch教程】--- Elasticsearch JavaApi 文档查询操作(二十)

丑过三八线 2023-07-10 原文

Elasticsearch JavaApi 文档查询操作

在前面的restful api测试的过程中,我们使用的大量的参数提交的方式进行文档的查询操作。例如:全量查询,分页查询,模糊查询等等。 那java api其实也是提供了对应的查询操作功能的。

全量查询

全量查询就是不提交任何的查询条件直接将ES上有的文档数据一次性的查询出来。查询的核心是要构造一个org.elasticsearch.action.search.SearchRequest;对象,并且使用client.search()方法即可查询。下面是java api查询文档的步骤:

  1. 构造Httphost对象。
  2. 构造RestClientBuilder对象。
  3. 构建客户端对象RestHighLevelClient对象。
  4. 构造org.elasticsearch.action.search.SearchRequest.
  5. 使用indices()方法设置要查询文档所在的index
  6. 发起请求得到查询结果响应。
  7. 关闭客户端链接
    测试代码如下:
package com.maomao.elastic.search.query;

import org.apache.http.HttpHost;
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.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.search.SearchHits;

/**
 * 简单的全量查询
 */
public class DocQueryAll {

    public static void main(String[] args) throws Exception {
        HttpHost host = new HttpHost("127.0.0.1", 9200, "http");
        RestClientBuilder builder = RestClient.builder(host);
        RestHighLevelClient client = new RestHighLevelClient(builder);

        // 查询数据
        SearchRequest request = new SearchRequest();
        request.indices("teacher");
        SearchResponse search = client.search(request, RequestOptions.DEFAULT);
        SearchHits hits = search.getHits();
        hits.forEach(System.out::println);

        client.close();
    }
}

由于我们将执行后的结果的hits进行了打印。所以程序运行的输出为:

{
  "_index" : "teacher",
  "_type" : "_doc",
  "_id" : "7001",
  "_score" : 1.0,
  "_source" : {
    "name" : "方腊",
    "sex" : "男",
    "age" : "38",
    "title" : "教授"
  }
}
{
  "_index" : "teacher",
  "_type" : "_doc",
  "_id" : "7002",
  "_score" : 1.0,
  "_source" : {
    "name" : "宋江",
    "sex" : "男",
    "age" : "35",
    "title" : "副教授"
  }
}
{
  "_index" : "teacher",
  "_type" : "_doc",
  "_id" : "7003",
  "_score" : 1.0,
  "_source" : {
    "name" : "花荣",
    "sex" : "男",
    "age" : "25",
    "title" : "助教"
  }
}
{
  "_index" : "teacher",
  "_type" : "_doc",
  "_id" : "7004",
  "_score" : 1.0,
  "_source" : {
    "name" : "孙二娘",
    "sex" : "女",
    "age" : "28",
    "title" : "副教授"
  }
}

Process finished with exit code 0

从执行的结果可以看出, 我们把teacher索引下的内容都正常的请求下来了。java api的全量查询结果其实也是和restful api是基本一致的。

条件查询

条件查询其实就是在全量查询的基础上进行怎么条件内容. 条件的构建分了3步走:

  1. 构建一个QueryBuilder,改对象由QueryBuilders来构建,比如,年龄等于35的,QueryBuilder age = QueryBuilders.termQuery("age", 35);
  2. 创建一个org.elasticsearch.search.builder.SearchSourceBuilder,直接new就ok。
  3. 然后把条件弄进SearchSourceBuilder,弄进去就用query()方法.
  4. SearchSourceBuilder设置到SearchRequestrequest.source(query);
    以上就已经把条件弄到请求里面去了。样例代码如下:
package com.maomao.elastic.search.query;

import org.apache.http.HttpHost;
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.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;

/**
 * 条件查询
 */
public class DocQueryCondition {

    public static void main(String[] args) throws Exception {
        HttpHost host = new HttpHost("127.0.0.1", 9200, "http");
        RestClientBuilder builder = RestClient.builder(host);
        RestHighLevelClient client = new RestHighLevelClient(builder);

        // 条件查询
        SearchRequest request = new SearchRequest();
        request.indices("teacher");
        // 添加条件
        QueryBuilder age = QueryBuilders.termQuery("age", 35);
        SearchSourceBuilder query = new SearchSourceBuilder().query(age);
        request.source(query);

        SearchResponse search = client.search(request, RequestOptions.DEFAULT);
        SearchHits hits = search.getHits();
        hits.forEach(System.out::println);

        client.close();
    }
}

执行结果:

{
  "_index" : "teacher",
  "_type" : "_doc",
  "_id" : "7002",
  "_score" : 1.0,
  "_source" : {
    "name" : "宋江",
    "sex" : "男",
    "age" : "35",
    "title" : "副教授"
  }
}

结果仅匹配到了35岁的宋江大哥.
我们再测试一下

package com.maomao.elastic.search.query;

import org.apache.http.HttpHost;
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.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;

/**
 * 条件查询
 */
public class DocQueryCondition {

    public static void main(String[] args) throws Exception {
        HttpHost host = new HttpHost("127.0.0.1", 9200, "http");
        RestClientBuilder builder = RestClient.builder(host);
        RestHighLevelClient client = new RestHighLevelClient(builder);

        // 条件查询
        SearchRequest request = new SearchRequest();
        request.indices("teacher");
        // 添加条件
        QueryBuilder age = QueryBuilders.termQuery("name", "宋");
        SearchSourceBuilder query = new SearchSourceBuilder().query(age);
        request.source(query);

        SearchResponse search = client.search(request, RequestOptions.DEFAULT);
        SearchHits hits = search.getHits();
        hits.forEach(System.out::println);

        client.close();
    }

}

这次使用的是name字段,值是
查询结果:

{
  "_index" : "teacher",
  "_type" : "_doc",
  "_id" : "7002",
  "_score" : 1.2613049,
  "_source" : {
    "name" : "宋江",
    "sex" : "男",
    "age" : "35",
    "title" : "副教授"
  }
}

分页查询

分页查询就是在条件查询的SearchSourceBuilder设置起查询文档的起始位置。
分页查询代码如下:

package com.maomao.elastic.search.query;

import org.apache.http.HttpHost;
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.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;

/**
 * 分页查询
 */
public class DocQueryPagination {

    public static void main(String[] args) throws Exception {
        HttpHost host = new HttpHost("127.0.0.1", 9200, "http");
        RestClientBuilder builder = RestClient.builder(host);
        RestHighLevelClient client = new RestHighLevelClient(builder);

        // 3. 分页查询
        SearchRequest request = new SearchRequest();
        request.indices("teacher");

        // 添加条件
        QueryBuilder queryBuilder = QueryBuilders.matchAllQuery();//全查
        SearchSourceBuilder query = new SearchSourceBuilder().query(queryBuilder);
        query.from(0);
        query.size(2); //每页显示几条

        request.source(query);

        SearchResponse search = client.search(request, RequestOptions.DEFAULT);
        SearchHits hits = search.getHits();
        hits.forEach(System.out::println);

        client.close();
    }

}

执行结果:

{
  "_index" : "teacher",
  "_type" : "_doc",
  "_id" : "7001",
  "_score" : 1.0,
  "_source" : {
    "name" : "方腊",
    "sex" : "男",
    "age" : "38",
    "title" : "教授"
  }
}
{
  "_index" : "teacher",
  "_type" : "_doc",
  "_id" : "7002",
  "_score" : 1.0,
  "_source" : {
    "name" : "宋江",
    "sex" : "男",
    "age" : "35",
    "title" : "副教授"
  }
}

从结果上可以看到,分页查询仅查询到了一页数据。

查询结果排序

查询结果排序就是在SearchSourceBuildersort方法进行。
例如:

 SearchSourceBuilder query = new SearchSourceBuilder().query(queryBuilder);
 query.sort("age", SortOrder.DESC);//年龄从大大小

以下是全量查询,以年龄倒序的查询例子.

package com.maomao.elastic.search.query;

import org.apache.http.HttpHost;
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.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;

/**
 * 查询排序
 */
public class DocQueryOrder {

    public static void main(String[] args) throws Exception {
        HttpHost host = new HttpHost("127.0.0.1", 9200, "http");
        RestClientBuilder builder = RestClient.builder(host);
        RestHighLevelClient client = new RestHighLevelClient(builder);

        // 3. 分页查询
        SearchRequest request = new SearchRequest();
        request.indices("teacher");

        // 添加条件
        QueryBuilder queryBuilder = QueryBuilders.matchAllQuery();//全查
        SearchSourceBuilder query = new SearchSourceBuilder().query(queryBuilder);
        query.sort("age", SortOrder.DESC);//年龄从大大小

        request.source(query);

        SearchResponse search = client.search(request, RequestOptions.DEFAULT);
        SearchHits hits = search.getHits();
        hits.forEach(System.out::println);

        client.close();
    }
}

查询输出结果:

{
  "_index" : "teacher",
  "_type" : "_doc",
  "_id" : "7001",
  "_score" : null,
  "_source" : {
    "name" : "方腊",
    "sex" : "男",
    "age" : "38",
    "title" : "教授"
  },
  "sort" : [
    38
  ]
}
{
  "_index" : "teacher",
  "_type" : "_doc",
  "_id" : "7002",
  "_score" : null,
  "_source" : {
    "name" : "宋江",
    "sex" : "男",
    "age" : "35",
    "title" : "副教授"
  },
  "sort" : [
    35
  ]
}
{
  "_index" : "teacher",
  "_type" : "_doc",
  "_id" : "7004",
  "_score" : null,
  "_source" : {
    "name" : "孙二娘",
    "sex" : "女",
    "age" : "28",
    "title" : "副教授"
  },
  "sort" : [
    28
  ]
}
{
  "_index" : "teacher",
  "_type" : "_doc",
  "_id" : "7003",
  "_score" : null,
  "_source" : {
    "name" : "花荣",
    "sex" : "男",
    "age" : "25",
    "title" : "助教"
  },
  "sort" : [
    25
  ]
}

从输出结果可以看出,结果的顺序是按照年龄从大到小的形式输出。

过滤字段

在我们查询的过程中,我们可能存在只需要部分字段的情况。
下面例子是仅获取,姓名和性别的过滤的例子。

package com.maomao.elastic.search.query;

import org.apache.http.HttpHost;
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.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;

/**
 * 字段过滤查询
 */
public class DocQueryFieldFilter {

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

        HttpHost host = new HttpHost("127.0.0.1", 9200, "http");
        RestClientBuilder builder = RestClient.builder(host);
        RestHighLevelClient client = new RestHighLevelClient(builder);

        // 3. 分页查询
        SearchRequest request = new SearchRequest();
        request.indices("teacher");

        // 添加条件
        QueryBuilder queryBuilder = QueryBuilders.matchAllQuery();//全查
        SearchSourceBuilder query = new SearchSourceBuilder().query(queryBuilder);

//        过滤字段
        query.fetchSource(new String[]{"name", "sex"}, null);
        request.source(query);

        SearchResponse search = client.search(request, RequestOptions.DEFAULT);
        SearchHits hits = search.getHits();
        hits.forEach(System.out::println);

        client.close();

    }

}

执行查询的结果为:

{
  "_index" : "teacher",
  "_type" : "_doc",
  "_id" : "7001",
  "_score" : 1.0,
  "_source" : {
    "sex" : "男",
    "name" : "方腊"
  }
}
{
  "_index" : "teacher",
  "_type" : "_doc",
  "_id" : "7002",
  "_score" : 1.0,
  "_source" : {
    "sex" : "男",
    "name" : "宋江"
  }
}
{
  "_index" : "teacher",
  "_type" : "_doc",
  "_id" : "7003",
  "_score" : 1.0,
  "_source" : {
    "sex" : "男",
    "name" : "花荣"
  }
}
{
  "_index" : "teacher",
  "_type" : "_doc",
  "_id" : "7004",
  "_score" : 1.0,
  "_source" : {
    "sex" : "女",
    "name" : "孙二娘"
  }
}

从返回的内容可以看出,仅查询了sexname

多条件联合查询

多条件查询需要用到BoolQueryBuilder,通过QueryBuilders.boolQuery();获取. 多个条件的满足关系。

  1. 必须满足must
  2. 必须不满足mustNot
  3. 可以满足should
    例子,查询年龄必须等于35.性别必须等于
    样例代码:
package com.maomao.elastic.search.query;

import org.apache.http.HttpHost;
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.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;

/**
 * 组合条件查询
 */
public class DocQueryMultCondition {

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

        HttpHost host = new HttpHost("127.0.0.1", 9200, "http");
        RestClientBuilder builder = RestClient.builder(host);
        RestHighLevelClient client = new RestHighLevelClient(builder);

        // 3. 分页查询
        SearchRequest request = new SearchRequest();
        request.indices("teacher");

        // 组合条件
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();//全查
        queryBuilder.must(QueryBuilders.matchQuery("age", "35"));
        queryBuilder.must(QueryBuilders.matchQuery("sex", "男"));

        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().query(queryBuilder);
        request.source(searchSourceBuilder);

        SearchResponse search = client.search(request, RequestOptions.DEFAULT);
        SearchHits hits = search.getHits();
        hits.forEach(System.out::println);

        client.close();

    }
}

由于ES的文档中只有宋江满足。所以查询结果为:

{
  "_index" : "teacher",
  "_type" : "_doc",
  "_id" : "7002",
  "_score" : 1.3566749,
  "_source" : {
    "name" : "宋江",
    "sex" : "男",
    "age" : "35",
    "title" : "副教授"
  }
}

范围查询

范围查询在工程实践中也是常常被要求的,比如需要得到30岁到40岁的teacher. 需要用到RangeQueryBuilder
样例代码:

package com.maomao.elastic.search.query;

import org.apache.http.HttpHost;
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.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;

/**
 * 组合条件查询
 */
public class DocQueryRange {

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

        HttpHost host = new HttpHost("127.0.0.1", 9200, "http");
        RestClientBuilder builder = RestClient.builder(host);
        RestHighLevelClient client = new RestHighLevelClient(builder);

        // 3. 分页查询
        SearchRequest request = new SearchRequest();
        request.indices("teacher");

        // 组合条件
        RangeQueryBuilder query = QueryBuilders.rangeQuery("age");
        query.gte(30);
        query.lte(40);

        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().query(query);
        request.source(searchSourceBuilder);

        SearchResponse search = client.search(request, RequestOptions.DEFAULT);
        SearchHits hits = search.getHits();
        hits.forEach(System.out::println);
        
        client.close();

    }
}

查询结果:

{
  "_index" : "teacher",
  "_type" : "_doc",
  "_id" : "7001",
  "_score" : 1.0,
  "_source" : {
    "name" : "方腊",
    "sex" : "男",
    "age" : "38",
    "title" : "教授"
  }
}
{
  "_index" : "teacher",
  "_type" : "_doc",
  "_id" : "7002",
  "_score" : 1.0,
  "_source" : {
    "name" : "宋江",
    "sex" : "男",
    "age" : "35",
    "title" : "副教授"
  }
}

模糊查询

package com.maomao.elastic.search.query;

import org.apache.http.HttpHost;
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.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.unit.Fuzziness;
import org.elasticsearch.index.query.FuzzyQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;

/**
 * 模糊查询
 */
public class DocFuzzyQuery {

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

        HttpHost host = new HttpHost("127.0.0.1", 9200, "http");
        RestClientBuilder builder = RestClient.builder(host);
        RestHighLevelClient client = new RestHighLevelClient(builder);

        // 3. 分页查询
        SearchRequest request = new SearchRequest();
        request.indices("teacher");

        // 组合条件
        FuzzyQueryBuilder query = QueryBuilders.fuzzyQuery("name", "宋").fuzziness(Fuzziness.ONE);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().query(query);
        request.source(searchSourceBuilder);

        SearchResponse search = client.search(request, RequestOptions.DEFAULT);
        SearchHits hits = search.getHits();
        hits.forEach(System.out::println);

        client.close();

    }

}

高亮查询

package com.maomao.elastic.search.query;

import org.apache.http.HttpHost;
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.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.unit.Fuzziness;
import org.elasticsearch.index.query.FuzzyQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;

/**
 * 模糊查询
 */
public class DocHigLightQuery {

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

        HttpHost host = new HttpHost("127.0.0.1", 9200, "http");
        RestClientBuilder builder = RestClient.builder(host);
        RestHighLevelClient client = new RestHighLevelClient(builder);

        // 3. 分页查询
        SearchRequest request = new SearchRequest();
        request.indices("teacher");

        // 组合条件
        TermQueryBuilder query = QueryBuilders.termQuery("name", "宋");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().query(query);
        request.source(searchSourceBuilder);
        HighlightBuilder highlight = SearchSourceBuilder.highlight();
        highlight.preTags("<font color='red'");
        highlight.postTags("/font>");
        highlight.field("name");
        searchSourceBuilder.highlighter(highlight);
        SearchResponse search = client.search(request, RequestOptions.DEFAULT);
        SearchHits hits = search.getHits();
        hits.forEach(System.out::println);

        client.close();

    }

}

响应结果:

{
  "_index" : "teacher",
  "_type" : "_doc",
  "_id" : "7002",
  "_score" : 1.2613049,
  "_source" : {
    "name" : "宋江",
    "sex" : "男",
    "age" : "35",
    "title" : "副教授"
  },
  "highlight" : {
    "name" : [
      "<font color='red'宋/font>江"
    ]
  }
}

聚合查询

查询最大年龄

package com.maomao.elastic.search.query;

import org.apache.http.HttpHost;
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.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.metrics.ParsedMax;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;

/**
 * 模糊查询
 */
public class DocPolyQuery {

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

        HttpHost host = new HttpHost("127.0.0.1", 9200, "http");
        RestClientBuilder builder = RestClient.builder(host);
        RestHighLevelClient client = new RestHighLevelClient(builder);

        // 3. 分页查询
        SearchRequest request = new SearchRequest();
        request.indices("teacher");

        // 组合条件
        AggregationBuilder query = AggregationBuilders.max("maxAge").field("age");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().aggregation(query);
        request.source(searchSourceBuilder);

        SearchResponse search = client.search(request, RequestOptions.DEFAULT);
        System.out.println(((ParsedMax) search.getAggregations().get("maxAge")).getValue());
        System.out.println(search.getAggregations().getAsMap().get("maxAge").getName());
        SearchHits hits = search.getHits();
        hits.forEach(System.out::println);

        client.close();

    }

}

查询输出:

38.0
maxAge
{
  "_index" : "teacher",
  "_type" : "_doc",
  "_id" : "7001",
  "_score" : 1.0,
  "_source" : {
    "name" : "方腊",
    "sex" : "男",
    "age" : "38",
    "title" : "教授"
  }
}
{
  "_index" : "teacher",
  "_type" : "_doc",
  "_id" : "7002",
  "_score" : 1.0,
  "_source" : {
    "name" : "宋江",
    "sex" : "男",
    "age" : "35",
    "title" : "副教授"
  }
}
{
  "_index" : "teacher",
  "_type" : "_doc",
  "_id" : "7003",
  "_score" : 1.0,
  "_source" : {
    "name" : "花荣",
    "sex" : "男",
    "age" : "25",
    "title" : "助教"
  }
}
{
  "_index" : "teacher",
  "_type" : "_doc",
  "_id" : "7004",
  "_score" : 1.0,
  "_source" : {
    "name" : "孙二娘",
    "sex" : "女",
    "age" : "28",
    "title" : "副教授"
  }
}

Process finished with exit code 0

分组查询

分组查询也是聚合查询的一种,他可以按照某个字段进行分组,统计。比如统计个数.

package com.maomao.elastic.search.query;

import org.apache.http.HttpHost;
import org.apache.lucene.queryparser.flexible.standard.builders.GroupQueryNodeBuilder;
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.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.ParsedLongTerms;
import org.elasticsearch.search.aggregations.metrics.ParsedMax;
import org.elasticsearch.search.builder.SearchSourceBuilder;

/**
 * 分组查询
 */
public class DocGroupQuery {

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

        HttpHost host = new HttpHost("127.0.0.1", 9200, "http");
        RestClientBuilder builder = RestClient.builder(host);
        RestHighLevelClient client = new RestHighLevelClient(builder);

        // 3. 分页查询
        SearchRequest request = new SearchRequest();
        request.indices("teacher");

        // 分组查询
        AggregationBuilder query = AggregationBuilders.terms("ageGroup").field("age");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().aggregation(query);
        request.source(searchSourceBuilder);

        SearchResponse search = client.search(request, RequestOptions.DEFAULT);
        ((ParsedLongTerms) search.getAggregations().get("ageGroup")).getBuckets().forEach(item -> {
            System.out.println(item.getKey() + "===>>" + item.getDocCount());
        });

        client.close();

    }
}

输出结果’

25===>>1
28===>>1
35===>>1
38===>>1

有关【ElasticSearch教程】--- Elasticsearch JavaApi 文档查询操作(二十)的更多相关文章

  1. ruby - ECONNRESET (Whois::ConnectionError) - 尝试在 Ruby 中查询 Whois 时出错 - 2

    我正在用Ruby编写一个简单的程序来检查域列表是否被占用。基本上它循环遍历列表,并使用以下函数进行检查。require'rubygems'require'whois'defcheck_domain(domain)c=Whois::Client.newc.query("google.com").available?end程序不断出错(即使我在google.com中进行硬编码),并打印以下消息。鉴于该程序非常简单,我已经没有什么想法了-有什么建议吗?/Library/Ruby/Gems/1.8/gems/whois-2.0.2/lib/whois/server/adapters/base.

  2. ruby-on-rails - 在 Rails 和 ActiveRecord 中查询时忽略某些字段 - 2

    我知道我可以指定某些字段来使用pluck查询数据库。ids=Item.where('due_at但是我想知道,是否有一种方法可以指定我想避免从数据库查询的某些字段。某种反拔?posts=Post.where(published:true).do_not_lookup(:enormous_field) 最佳答案 Model#attribute_names应该返回列/属性数组。您可以排除其中一些并传递给pluck或select方法。像这样:posts=Post.where(published:true).select(Post.attr

  3. Matlab imread()读到了什么 (浅显 当复习文档了) - 2

    matlab打开matlab,用最简单的imread方法读取一个图像clcclearimg_h=imread('hua.jpg');返回一个数组(矩阵),往往是a*b*cunit8类型解释一下这个三维数组的意思,行数、数和层数,unit8:指数据类型,无符号八位整形,可理解为0~2^8的数三个层数分别代表RGB三个通道图像rgb最常用的是24-位实现方法,即RGB每个通道有256色阶(2^8)。基于这样的24-位RGB模型的色彩空间可以表现256×256×256≈1670万色当imshow传入了一个二维数组,它将以灰度方式绘制;可以把图像拆分为rgb三层,可以以灰度的方式观察它figure(1

  4. postman接口测试工具-基础使用教程 - 2

    1.postman介绍Postman一款非常流行的API调试工具。其实,开发人员用的更多。因为测试人员做接口测试会有更多选择,例如Jmeter、soapUI等。不过,对于开发过程中去调试接口,Postman确实足够的简单方便,而且功能强大。2.下载安装官网地址:https://www.postman.com/下载完成后双击安装吧,安装过程极其简单,无需任何操作3.使用教程这里以百度为例,工具使用简单,填写URL地址即可发送请求,在下方查看响应结果和响应状态码常用方法都有支持请求方法:getpostputdeleteGet、Post、Put与Delete的作用get:请求方法一般是用于数据查询,

  5. 在VMware16虚拟机安装Ubuntu详细教程 - 2

    在VMware16.2.4安装Ubuntu一、安装VMware1.打开VMwareWorkstationPro官网,点击即可进入。2.进入后向下滑动找到Workstation16ProforWindows,点击立即下载。3.下载完成,文件大小615MB,如下图:4.鼠标右击,以管理员身份运行。5.点击下一步6.勾选条款,点击下一步7.先勾选,再点击下一步8.去掉勾选,点击下一步9.点击下一步10.点击安装11.点击许可证12.在百度上搜索VM16许可证,复制填入,然后点击输入即可,亲测有效。13.点击完成14.重启系统,点击是15.双击VMwareWorkstationPro图标,进入虚拟机主

  6. hadoop安装之保姆级教程(二)之YARN的配置 - 2

    1.1.1 YARN的介绍 为克服Hadoop1.0中HDFS和MapReduce存在的各种问题⽽提出的,针对Hadoop1.0中的MapReduce在扩展性和多框架⽀持⽅⾯的不⾜,提出了全新的资源管理框架YARN. ApacheYARN(YetanotherResourceNegotiator的缩写)是Hadoop集群的资源管理系统,负责为计算程序提供服务器计算资源,相当于⼀个分布式的操作系统平台,⽽MapReduce等计算程序则相当于运⾏于操作系统之上的应⽤程序。 YARN被引⼊Hadoop2,最初是为了改善MapReduce的实现,但是因为具有⾜够的通⽤性,同样可以⽀持其他的分布式计算模

  7. sql - 查询忽略时间戳日期的时间范围 - 2

    我正在尝试查询我的Rails数据库(Postgres)中的购买表,我想查询时间范围。例如,我想知道在所有日期的下午2点到3点之间进行了多少次购买。此表中有一个created_at列,但我不知道如何在不搜索特定日期的情况下完成此操作。我试过:Purchases.where("created_atBETWEEN?and?",Time.now-1.hour,Time.now)但这最终只会搜索今天与那些时间的日期。 最佳答案 您需要使用PostgreSQL'sdate_part/extractfunction从created_at中提取小时

  8. ruby - 如何使用 Selenium Webdriver 根据 div 的内容执行操作? - 2

    我有一个使用SeleniumWebdriver和Nokogiri的Ruby应用程序。我想选择一个类,然后对于那个类对应的每个div,我想根据div的内容执行一个Action。例如,我正在解析以下页面:https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=puppies这是一个搜索结果页面,我正在寻找描述中包含“Adoption”一词的第一个结果。因此机器人应该寻找带有className:"result"的div,对于每个检查它的.descriptiondiv是否包含单词“adoption

  9. ruby-on-rails - 如何处理 Grape 中特定操作的过滤器之前? - 2

    我正在我的Rails项目中安装Grape以构建RESTfulAPI。现在一些端点的操作需要身份验证,而另一些则不需要身份验证。例如,我有users端点,看起来像这样:moduleBackendmoduleV1classUsers现在如您所见,除了password/forget之外的所有操作都需要用户登录/验证。创建一个新的端点也没有意义,比如passwords并且只是删除password/forget从逻辑上讲,这个端点应该与用户资源。问题是Grapebefore过滤器没有像except,only这样的选项,我可以在其中说对某些操作应用过滤器。您通常如何干净利落地处理这种情况?

  10. ruby-on-rails - 在 Ruby on Rails 中发送响应之前如何等待多个异步操作完成? - 2

    在我做的一些网络开发中,我有多个操作开始,比如对外部API的GET请求,我希望它们同时开始,因为一个不依赖另一个的结果。我希望事情能够在后台运行。我找到了concurrent-rubylibrary这似乎运作良好。通过将其混合到您创建的类中,该类的方法具有在后台线程上运行的异步版本。这导致我编写如下代码,其中FirstAsyncWorker和SecondAsyncWorker是我编写的类,我在其中混合了Concurrent::Async模块,并编写了一个名为“work”的方法来发送HTTP请求:defindexop1_result=FirstAsyncWorker.new.async.

随机推荐