Java中用Aggregation对Mongo聚合查询

版权声明:本文为神州灵云作者的原创文章,未经神州灵云允许不得转载。

本文作者:Lux

#前言:

接触mongo也有段时间了,在进行功能研发时经常用到mongo聚合查询,所以想整理一下mongo常用的聚合查询的函数,以及在java中实现的语法。也便于以后做一些简单的查询时有个例子可以参考 (fu zhi)。很多复杂的查询都是从简单的部分组合的,同时查询很多内容的话,用聚合管道进行字段筛选之后,再处理数据时会方便很多,也便于优化查询语句时的观看体验。

#1 前提配置:

##1.1 连接配置,使用自动配置方式,在applicaiton.properties中配置连接信息即可
spring.data.mongodb.host= ip
spring.data.mongodb.port= port
spring.data.mongodb.database = mongdbname

##1.2 java中使用
注入mongoTemplate对象 :
@Autowired
private MongoTemplate mongoTemplate;

#2 Aggregation常用函数

##2.1 Aggregation.group() : 聚合函数,将某个字段或者某个数组作为分组统计的依据,在group的基础上又扩展出以下函数:

2.1.1:sum() : 求和
2.1.2:max() : 获取最大值
2.1.3:min() : 获取最小值
2.1.4:avg() : 获取平均值
2.1.5:count() : 统计条目数
2.1.6: first () : 获取group by 后的某个字段的首个值
2.1.7:last() : 获取 group by 后的某个字段的最后一个值

##2.2 Aggregation.match() : 过滤函数,主要存储过滤数据的条件,输出符合条件的记录

##2.3 Aggregation.project(): 修改数据结构函数,将前面管道中的获取的字段进行重名,增加,修改字段等操作。

##2.4 Aggregation.sort(): 排序函数,将上级管道的内容按照某个字段进行排序并且输出。

##2.5 Aggregation.limit(): 限制输出函数,将聚合返回的内容限定在某个条目之内。

##2.6 Aggregation.skip(): 跳过指定数量的条目再开始返回数据的函数,通常和sort(),limit()配合,实现数据翻页查询等操作。

#3 查询主体:
##3.1 group by 聚合查询

3.1.1:对id做group

mongodb: 
db.table.aggregate([
    {
        "$group" : {
            "_id" : "$_id"
        }
    }
])
java:
Aggregation agg = Aggregation.newAggregation(
				Aggregation.group(new String[] {"id"})
        );

当然,单纯的做group by 不做输出大多数没啥用,一般都是配合输出函数来使用group by的。

3.1.2:以id为group by计算num的总值sum()

Mongo:
db.table.aggregate([
    {
        "$group" : {
            "_id" : "$_id", 
            "num" : {
                "$sum" : "$num"
            }
        }
    }
])
java:
Aggregation agg = Aggregation.newAggregation(
				Aggregation.group(new String[] {"_id"}).sum("num").as("num")
    			);

3.1.3:以id为group by找出num的最大值max()

Mongo:
db. table.aggregate([
    {
        "$group" : {
            "_id" : "$_id", 
            "num" : {
                "$max" : "$num"
            }
        }
    }
])
java:
Aggregation agg = Aggregation.newAggregation(
				Aggregation.group(new String[] {"_id"}).max("num").as("num")
    			);

3.1.4:以id为group by找出num的最小值min()

Mongo: 
db. table.aggregate([
    {
        "$group" : {
            "_id" : "$_id", 
            "num" : {
                "$min" : "$num"
            }
        }
    }
])
java:
Aggregation agg = Aggregation.newAggregation(
				Aggregation.group(new String[] {"_id"}).min("num").as("num")
    			);

3.1.5:以id为group by计算num的平均值avg()

Mongo:
db. table.aggregate([
    {
        "$group" : {
            "_id" : "$_id", 
            "num" : {
                "$avg" : "$num"
            }
        }
    }
])
java:
Aggregation agg = Aggregation.newAggregation(
				Aggregation.group(new String[] {"_id"}).avg("num").as("num")
    			);

3.1.6:对id做记数统计count()

 Mongo:
db.table.aggregate([
    {
        "$group" : {
            "_id" : "$_id", 
            "count" : {
                "$sum" : NumberInt(1)
            }
        }
    }
])
java:
Aggregation agg = Aggregation.newAggregation(
Aggregation.group(new String[] {"_id"}).count().as("count")
);

3.1.7:以id为group by获取name的第一个值first()

 Mongo:
db. table.aggregate([
    {
        "$group" : {
            "_id" : "$_id", 
            "name" : {
                "$first" : "$name"
            }
        }
    }
])
java:
Aggregation agg = Aggregation.newAggregation(
Aggregation.group(new String[] {"_id"}).first("name").as("name")
);

3.1.8:以id为group by获取name的最后一个值last()

Mongo:
db. table.aggregate([
    {
        "$group" : {
            "_id" : "$_id", 
            "name" : {
                "$last" : "$name"
            }
        }
    }
])

java:
Aggregation agg = Aggregation.newAggregation(
		Aggregation.group(new String[] {"_id"}).last("name").as("name")
    	);

3.1.9:组合一下,以id为group by获取num的和(sum)以及name的第一个值(first)

Mongo:
db. table.aggregate([
    {
        "$group" : {
            "_id" : "$_id", 
            "num" : {
                "$sum" : "$num"
            }, 
            "name" : {
                "$first" : "$name"
            }
        }
}
])

java:
Aggregation agg = Aggregation.newAggregation(
			Aggregation.group(new String[] {"_id"}).
sum("num").as("num").
first("name").as("name")
    	);

##3.2 match管道过滤
Match中设置的是记录的过滤条件。过滤条件参考Criteria的使用
举个例子:

		Mongo:
			db. table.aggregate([
   {
        "$match" : {
            "$and" : [
                {
                    "_id" : {
                        "$exists" : true
                    }
                }
            ]
        }
    }, 
    {
        "$group" : {
            "_id" : "$_id", 
            "num" : {
                "$sum" : "$num"
            }, 
            "name" : {
                "$first" : "$name"
            }
        }
    }
])	
Java:
	//定义Criteria类集合
    	List<Criteria> where = new ArrayList<Criteria>();
    	
    	//添加条件
    	where.add(new Criteria().where("_id").exists(true));
    	
    	//初始化聚合
    	Aggregation agg = Aggregation.newAggregation(
Aggregation.match(new Criteria().andOperator((Criteria[]) where.
toArray(new Criteria[where.size()]))),
			Aggregation.group(new String[] {"_id"}).sum("num").as("num").first("name").as("name")
    			);

##3.3 Aggregation.project()筛选需要的字段
举个例子:按照_id group by,然后将num做取和处理,获取name的first值和last值,再用project将id,firstName,num取出,并且将lastName重命名为name

Mongo:
			db.table.aggregate([
    {
        "$group" : {
            "_id" : "$_id", 
            "num" : {
                "$sum" : "$num"
            }, 
            "firstName" : {
                "$first" : "$name"
            }, 
            "lastName" : {
                "$last" : "$name"
            }
        }
    }, 
    {
        "$project" : {
            "_id" : NumberInt(1), 
            "num" : NumberInt(1), 
            "firstName" : NumberInt(1), 
            "name" : "$lastName"
        }
    }
])
		Java:
			//初始化聚合
    	Aggregation agg = Aggregation.newAggregation(
    			Aggregation.group(new String[] {"_id"}).sum("num").as("num").
	    			first("name").as("firstName").
	    			last("name").as("lastName"),
			Aggregation.project("_id", "num", "firstName").
and("lastName").as("name")//重新挑选字段
       	 );

##3.4 sort,limit,skip组合使用
举个例子:将id聚合,然后将num做求和处理。并且将sum(num)的值进行降序排序,跳过前十条记录后,取出前两条记录。

Mongo:
db.table.aggregate([
    {
        "$group" : {
            "_id" : "$_id", 
            "num" : {
                "$sum" : "$num"
            } 
        }
    }, 
    {
        "$sort" : {
            "num" : NumberInt(-1)
        }
    }, 
    {
        "$skip" : NumberInt(10)
    }, 
    {
        "$limit" : NumberInt(2)
    }
]
)
	Java:
		Aggregation agg = Aggregation.newAggregation(
    			Aggregation.group(new String[] {"_id"}).sum("num").as("num").
first("name").as("firstName").
last("name").as("lastName"),
				Aggregation.sort(Direction.DESC, "num"),		//将num降序
				Aggregation.skip(10),					//从第10条记录开始
				Aggregation.limit(2)					 //取两条数据
        	);

对于mongo的聚合管道还有一些函数,比如
$unwind:将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。
$cond: 将文档中的值做if操作,满足的进行某项分支,不满足的进行另一项统计。
$goNear:$goNear会返回一些坐标值,这些值以按照距离指定点距离由近到远进行排序。
等等。

神州灵云公司官网(二维码).png

Elasticsearch 聚合查询Aggregation)是一种用于对数据进行多维度分析的功能。聚合查询可以用于分析数据的分布情况、计算数据的统计信息、生成图表等。在 Elasticsearch 中,聚合查询是通过使用特定的聚合器(Aggregator)来完成的。 Java 中使用 Elasticsearch 聚合查询需要使用 Elasticsearch Java API。首先需要创建一个 SearchRequest 对象,并设置需要查询的索引和查询条件。然后创建一个 AggregationBuilder 对象,用于定义聚合查询的规则和参数。最后将 AggregationBuilder 对象添加到 SearchRequest 中,执行查询操作。 以下是一个简单的 Java 代码示例,用于查询某个索引下的数据,并按照某个字段进行分组聚合查询: ``` SearchRequest searchRequest = new SearchRequest("index_name"); SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); TermsAggregationBuilder aggregationBuilder = AggregationBuilders.terms("group_by_field").field("field_name"); searchSourceBuilder.aggregation(aggregationBuilder); searchRequest.source(searchSourceBuilder); SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT); Terms terms = searchResponse.getAggregations().get("group_by_field"); for (Terms.Bucket bucket : terms.getBuckets()) { String key = bucket.getKeyAsString(); long count = bucket.getDocCount(); System.out.println("key: " + key + ", count: " + count); } ``` 在上面的代码中,首先创建了一个 SearchRequest 对象,设置需要查询的索引和查询条件。然后创建了一个 TermsAggregationBuilder 对象,用于按照某个字段进行分组聚合查询。最后将 TermsAggregationBuilder 对象添加到 SearchRequest 中,执行查询操作。 查询结果会返回一个 Terms 对象,其中包含了分组聚合查询的结果。可以使用 Terms 对象的 getBuckets() 方法获取分组聚合查询的结果列表。每个分组聚合查询结果由一个 Terms.Bucket 对象表示,其中包含了分组聚合查询的键值和文档数量等信息。 以上是简单的聚合查询示例,Elasticsearch 聚合查询功能非常强大,支持多种聚合器和聚合规则,可以根据具体需求进行调整和扩展。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值