mongTemplate实现group分组查询aggregation

本文介绍了如何在MongoService中使用Aggregation进行分组操作,展示了如何构造聚合查询并使用$group阶段对数据进行分组,同时强调了_id字段的作用和真正的字段映射。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MongoService封装

<T> List<T> group(Class<T> clazz, Aggregation aggregation,String documentName);

MongoServiceImpl实现类

@Override
	public <T> List<T> group(Class<T> clazz, Aggregation aggregation,String documentName) {
		// 执行聚合查询
		//aggegation:所有条件的封装 , CTL_HEART_BEAT:集合/表 ,DeviceGroupByResult.class:接收数据对象
		AggregationResults<T> aggregate = mongoTemplate.aggregate(aggregation, documentName, clazz);
		//这里就很友好了
		return aggregate.getMappedResults();

	}

实践

             // 构建聚合查询
                Aggregation aggregation = Aggregation.newAggregation(
                        Aggregation.match(Criteria.where("_id").ne(null)),
                        Aggregation.group("otel_id")
                                .first("otel_id").as("otel_id")
                                .first("nel_id").as("nel_id")

                );
                List<Price> priceList = mongoService.group(Price.class, aggregation, "min_price");
                

注意管道的分组

在给定的聚合管道中,$group 阶段指定了 _id 字段作为分组依据,而且使用了 $otel_id 作为它的值。这意味着分组的结果将以 otel_id 字段的值作为分组的标识符。

因此,在 $group 阶段的结果中,会产生一个 _id 字段,其值与原始文档中的 otel_id 字段的值相对应。换句话说,_id 字段是用于表示分组的唯一标识符,而不再保持原始字段名。

使用真正的字段映射

Aggregation aggregation = Aggregation.newAggregation(
    Aggregation.match(Criteria.where("otel_id").ne(null)),
    Aggregation.group("otel_id")
        .count().as("count")
        .first("field1").as("field1")
        .first("field2").as("field2")
        .first("field3").as("field3")
        // 添加其他需要返回的字段
);

### Elasticsearch 实现分组查询的代码示例 在 Elasticsearch 中,分组查询通常通过聚合(Aggregation)功能实现。以下是使用 Java 和 Elasticsearch 客户端库实现分组查询的一个完整示例。 #### 1. 添加依赖 首先,在 `pom.xml` 文件中添加 Elasticsearch 高级 REST 客户端依赖: ```xml <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>elasticsearch-rest-high-level-client</artifactId> <version>7.10.2</version> </dependency> ``` 此依赖允许 Java 应用程序与 Elasticsearch 进行交互[^1]。 #### 2. 创建 Elasticsearch 客户端 初始化一个 Elasticsearch 客户端实例以连接到 Elasticsearch 服务: ```java RestHighLevelClient client = new RestHighLevelClient( RestClient.builder(new HttpHost("localhost", 9200, "http"))); ``` #### 3. 定义分组查询 以下是一个基于字段进行分组的聚合查询示例。假设我们有一个索引 `products`,其中包含 `category` 字段,需要按该字段进行分组统计: ```java SearchRequest searchRequest = new SearchRequest("products"); SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); // 定义分组聚合 TermsAggregationBuilder aggregation = AggregationBuilders .terms("group_by_category") .field("category.keyword") // 使用 keyword 类型字段进行分组 .size(10); // 设置返回的分组数量 sourceBuilder.aggregation(aggregation); searchRequest.source(sourceBuilder); try { SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT); // 获取分组结果 Terms terms = searchResponse.getAggregations().get("group_by_category"); for (Terms.Bucket bucket : terms.getBuckets()) { String key = bucket.getKeyAsString(); // 分组键值 long docCount = bucket.getDocCount(); // 每个分组中的文档数量 System.out.println("Category: " + key + ", Document Count: " + docCount); } } catch (IOException e) { e.printStackTrace(); } finally { try { client.close(); } catch (IOException e) { e.printStackTrace(); } } ``` #### 4. 结果解释 上述代码执行后,会输出每个 `category` 的分组结果及其对应的文档数量。例如: ``` Category: Electronics, Document Count: 50 Category: Books, Document Count: 30 Category: Clothing, Document Count: 20 ``` #### 5. 扩展:分组后求和 如果需要在分组的基础上对某个字段(如 `price`)进行求和操作,可以嵌套聚合: ```java TermsAggregationBuilder aggregation = AggregationBuilders .terms("group_by_category") .field("category.keyword") .subAggregation(AggregationBuilders.sum("total_price").field("price")); // 嵌套求和聚合 sourceBuilder.aggregation(aggregation); ``` 获取结果时,可以通过以下方式访问求和值: ```java for (Terms.Bucket bucket : terms.getBuckets()) { String key = bucket.getKeyAsString(); double totalPrice = bucket.getAggregations().get("total_price").getValue(); System.out.println("Category: " + key + ", Total Price: " + totalPrice); } ``` #### 注意事项 - 确保字段类型正确。对于分组字段(如 `category`),建议使用 `keyword` 类型而非 `text` 类型[^1]。 - 如果数据量较大,可以通过调整 `.size()` 参数控制返回的分组数量[^3]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值