需求:根据活动参与人数(members.size)对所有活动做排序(源数据存储在mongoDB) (Java实现)
数据结构如下:
{
"_id": ObjectId("64abc59d64b672069c437bce"),
"topic":"歌唱比赛"
"members": {
"001": [
"name":"张三"
"age":"20"
],
"002": [
"name":"李四"
"age":"25"
],
"003": [
"name":"王五"
"age":"23"
],
},
"status": "ended"
}
{
"_id": ObjectId("64abc59d64b672069c437bce"),
"topic":"生日会"
"members": {
"006": [
"name":"刀哥"
"age":"20"
],
"102": [
"name":"小虎"
"age":"25"
]
},
"status": "ended"
}
因为数据量比较大 所以不能查询出结果再排序处理。
Aggregation聚合查询中size函数只能对数组进行统计,不能处理这种数据结构
您好,可以使用以下聚合管道来实现根据 members 大小排序:
java
Aggregation agg = Aggregation.newAggregation(
Aggregation.sort(Sort.by(Sort.Direction.DESC, "members.size()"))
);
List<Document> documents = mongoTemplate.aggregate(agg, "collectionName", Document.class).getMappedResults();
主要步骤:
1. 使用`$objectToArray`将members对象转换为数组
2. 使用`$map`将数组中的每个元素提取出来
3. 使用`$size`统计每个元素的大小
4. 将大小结果添加进一个新的字段中
5. 根据新字段进行排序
完整聚合管道:
java
Aggregation agg = Aggregation.newAggregation(
Aggregation.project("topic")
.and("members").as("membersArray")
.and("status"),
Aggregation.unwind("membersArray"),
Aggregation.project("topic", "membersArray.v").as("member"),
Aggregation.group("topic")
.count().as("membersCount")
.push("member").as("members"),
Aggregation.sort(Sort.by(Sort.Direction.DESC, "membersCount")),
Aggregation.project("topic", "members", "membersCount")
);
这样就可以按照members大小排序了。