elasticsearch java实现类似sql group by

学习es查询总是想往sql方面靠齐,学习了一段时间,总结一些如下

BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
//添加时间范围过滤
        boolQueryBuilder.must(QueryBuilders.rangeQuery("@timestamp").format("yyyy-MM-dd HH:mm:ss").gte(conditionMap.get("createTimeB")).lte(conditionMap.get("createTimeE")));
        AggregationBuilder aggregationBuilder = AggregationBuilders
                .terms(查询字段别名).field(分组字段)
                .order(Terms.Order.aggregation(ES_COUNT_ALIAS, false))
                .size(10)
                .subAggregation(AggregationBuilders.count(统计字段别名).field(统计的字段));
        SearchRequestBuilder searchRequestBuilder = ElasticsearchHelper.getInstance().getClient().prepareSearch(ES_INDEX).setTypes(ES_TYPE)
                .setQuery(boolQueryBuilder)
                .addAggregation(aggregationBuilder)
                .setSize(0);

        SearchResponse sr = searchRequestBuilder.execute().actionGet();
        Terms genders = sr.getAggregations().get(统计字段别名);
for (Terms.Bucket entry : genders.getBuckets()) { list.add((String) entry.getKey()+"-("+entry.getDocCount()+")"); }
现在对上面进行修改,例如想group by 时间,并且按天来进行分组
AggregationBuilder aggregation = AggregationBuilders
                .dateHistogram("agg")
                .field("@timestamp")
                .format("yyyy-MM-dd")
                .dateHistogramInterval(DateHistogramInterval.DAY);
然后现在可能有新需求,group by 时间,姓名
AggregationBuilder nameAgg = AggregationBuilders.terms(姓名别名).field(姓名).size(10);
aggregation.subAggregation(nameAgg);
如果可以能需要进行名称统计,但是需要distinct
nameAgg.subAggregation(AggregationBuilders.cardinality(别名).field(姓名))


其他的总结如下

(1)统计某个字段的数量
  ValueCountBuilder vcb=  AggregationBuilders.count("count_uid").field("uid");
(2)去重统计某个字段的数量(有少量误差)
 CardinalityBuilder cb= AggregationBuilders.cardinality("distinct_count_uid").field("uid");
(3)聚合过滤
FilterAggregationBuilder fab= AggregationBuilders.filter("uid_filter").filter(QueryBuilders.queryStringQuery("uid:001"));
(4)按某个字段分组
TermsBuilder tb=  AggregationBuilders.terms("group_name").field("name");
(5)求和
SumBuilder  sumBuilder=	AggregationBuilders.sum("sum_price").field("price");
(6)求平均
AvgBuilder ab= AggregationBuilders.avg("avg_price").field("price");
(7)求最大值
MaxBuilder mb= AggregationBuilders.max("max_price").field("price"); 
(8)求最小值
MinBuilder min=	AggregationBuilders.min("min_price").field("price");
(9)按日期间隔分组
DateHistogramBuilder dhb= AggregationBuilders.dateHistogram("dh").field("date");
(10)获取聚合里面的结果
TopHitsBuilder thb=  AggregationBuilders.topHits("top_result");
(11)嵌套的聚合
NestedBuilder nb= AggregationBuilders.nested("negsted_path").path("quests");
(12)反转嵌套
AggregationBuilders.reverseNested("res_negsted").path("kps ");



Elasticsearch 5.4 提供了一种称为 SQL REST API 的方式,允许你使用 SQL 语句来查询 Elasticsearch。你可以使用 Java 客户端来调用 SQL REST API,实现 SQL 查询。 以下是一个使用 Java 客户端调用 Elasticsearch SQL REST API 的示例: ```java import org.apache.http.HttpHost; import org.elasticsearch.client.RestClient; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.client.sniff.Sniffer; import org.elasticsearch.client.transport.TransportClient; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.transport.TransportAddress; import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.builder.SearchSourceBuilder; import org.elasticsearch.transport.client.PreBuiltTransportClient; import java.net.InetAddress; import java.util.concurrent.TimeUnit; public class ElasticsearchSqlExample { public static void main(String[] args) throws Exception { // 创建 RestClient RestClient restClient = RestClient.builder( new HttpHost("localhost", 9200, "http")) .build(); // 创建 RestHighLevelClient RestHighLevelClient client = new RestHighLevelClient(restClient); // 创建 SQL 查询 XContentBuilder builder = XContentFactory.jsonBuilder(); builder.startObject(); { builder.field("query", "SELECT * FROM my_index WHERE age > 30"); } builder.endObject(); // 创建 SearchSourceBuilder SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); searchSourceBuilder.query(QueryBuilders.wrapperQuery(builder.string())); // 发起查询 SearchHit[] searchHits = client.search(searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS))) .getHits().getHits(); // 输出查询结果 for (SearchHit searchHit : searchHits) { System.out.println(searchHit.getSourceAsString()); } // 关闭客户端连接 client.close(); restClient.close(); } } ``` 在这个示例中,我们首先创建了一个 RestClient,然后使用它创建了一个 RestHighLevelClient。接着,我们使用 XContentBuilder 创建了一个 SQL 查询,并将其包装在一个 SearchSourceBuilder 中。最后,我们使用 RestHighLevelClient 发起查询,并输出查询结果。 需要注意的是,为了能够使用 SQL REST API,需要在 Elasticsearch 的配置文件中启用 xpack.sql.enabled 参数。同时,SQL 查询的语法和限制与传统的 SQL 有所不同,具体可以参考 Elasticsearch 的官方文档。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值