mongoDB聚合查询 根据文档size排序

需求:根据活动参与人数(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大小排序了。