You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MongoDB聚合查询:Go语言如何获取集合末尾的符合条件文档

解决Go语言Mongo聚合查询获取最新50条消息的问题

你当前的聚合查询返回最早消息的原因是连续执行了两次排序操作:先按create_date降序(把最新消息排前面),紧接着又按升序排序(把消息重新按最早到最新排列),最后$limit取前50条,自然得到的是最早的消息。

修改方案

只需要保留降序排序,去掉多余的升序排序阶段,或者根据需求在$limit后再调整排序顺序:

方案1:直接获取最新的50条(结果按最新到旧排列)

移除管道中的sortStage,聚合管道顺序改为:$match → $sort(降序) → $limit

修改后的代码:

func (r *Mongo) ChatHistory(ctx context.Context, chatID string, f *Filter) ([]*Message, error) {
    // 按create_date降序排序(最新消息在前)
    sortStage := bson.D{
        {
            Key: "$sort", Value: bson.D{
                primitive.E{Key: "create_date", Value: -1},
            },
        },
    }
    matchStage := bson.D{
        {
            Key: "$match",
            Value: bson.D{
                {Key: "chat_id", Value: chatID},
                {Key: "create_date", Value: bson.D{
                    {Key: "$lte", Value: 1675411054031}, // int64
                }},
            },
        },
    }
    limitStage := bson.D{primitive.E{Key: "$limit", Value: f.Count}}
    
    // 管道顺序:匹配条件 → 降序排序 → 取前50条
    cursor, err := r.colMessage.Aggregate(ctx, mongo.Pipeline{matchStage, sortStage, limitStage})
    if err != nil {
        l.Error().Err(err).Msg("failed find")
        return nil, err
    }
    // 后续处理逻辑...
}

方案2:获取最新50条,但结果按时间从旧到新排列

如果需要返回给客户端的消息是按时间正序(最早到最新)展示,可在$limit后添加升序排序:

修改后的管道顺序:$match → $sort(降序) → $limit → $sort(升序)

代码示例:

func (r *Mongo) ChatHistory(ctx context.Context, chatID string, f *Filter) ([]*Message, error) {
    sortDescStage := bson.D{
        {Key: "$sort", Value: bson.D{{Key: "create_date", Value: -1}}},
    }
    matchStage := bson.D{
        {
            Key: "$match",
            Value: bson.D{
                {Key: "chat_id", Value: chatID},
                {Key: "create_date", Value: bson.D{{Key: "$lte", Value: 1675411054031}}},
            },
        },
    }
    limitStage := bson.D{primitive.E{Key: "$limit", Value: f.Count}}
    sortAscStage := bson.D{
        {Key: "$sort", Value: bson.D{{Key: "create_date", Value: 1}}},
    }
    
    // 管道顺序:匹配 → 降序取最新50 → 升序排列返回
    cursor, err := r.colMessage.Aggregate(ctx, mongo.Pipeline{matchStage, sortDescStage, limitStage, sortAscStage})
    if err != nil {
        l.Error().Err(err).Msg("failed find")
        return nil, err
    }
    // 后续处理逻辑...
}

关键说明

  • $sort阶段的Value: -1代表降序(最新的消息排在前面),Value: 1代表升序(最早的消息排在前面)
  • 避免无意义的重复排序,减少性能消耗

内容的提问来源于stack exchange,提问作者alex

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 14:10:34