drinker888 2023-07-11 15:55 采纳率: 0%
浏览 13

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函数只能对数组进行统计,不能处理这种数据结构

  • 写回答

2条回答 默认 最新

  • IT论之程序员 2023-07-11 20:51
    关注
    
    您好,可以使用以下聚合管道来实现根据 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大小排序了。
    
    评论

报告相同问题?

问题事件

  • 创建了问题 7月11日