Golang MongoDB实现自定义排序:订单状态优先级排序需求
解决方案:MongoDB自定义订单状态排序(Golang驱动)
要实现IN_PROGRESS优先、其次ON_DELIVERY、最后DELIVERED的自定义排序,普通字段排序无法满足需求,需借助MongoDB聚合管道实现,以下是两种可行方案:
方案一:添加权重字段排序(推荐,易扩展)
通过$addFields给每个订单文档附加权重字段,不同状态对应不同权重值,再按权重升序排序(权重越小越靠前)。
Golang代码示例:
// 构建聚合管道 pipeline := mongo.Pipeline{ // 给不同状态的订单分配排序权重 {{"$addFields", bson.D{ {"sort_weight", bson.D{ {"$switch", bson.D{ {"branches", bson.A{ bson.D{{"case", bson.D{{"$eq", bson.A{"$status", "IN_PROGRESS"}}}}, {"then", 0}}, bson.D{{"case", bson.D{{"$eq", bson.A{"$status", "ON_DELIVERY"}}}}, {"then", 1}}, bson.D{{"case", bson.D{{"$eq", bson.A{"$status", "DELIVERED"}}}}, {"then", 2}}, }}, {"default", 2}, // 默认给DELIVERED权重,避免未知状态干扰排序 }}, }}, }}}, // 按权重升序排序 {{"$sort", bson.D{{"sort_weight", 1}}}}, } // 执行聚合查询 cursor, err := model.Collection.Aggregate(ctx, pipeline) if err != nil { // 处理查询错误 } defer cursor.Close(ctx) // 解码结果到订单模型 var orders []YourOrderModel if err := cursor.All(ctx, &orders); err != nil { // 处理解码错误 }
如果需要保留原有过滤条件,在管道最前面加入$match阶段即可:
pipeline = append(mongo.Pipeline{{{"$match", filter}}}, pipeline...)
该方案优势在于后续新增状态时,只需在branches中补充对应规则,逻辑清晰易维护。
方案二:用$indexOfArray直接排序(简洁高效)
利用$indexOfArray函数获取状态在自定义顺序数组中的索引,直接按索引升序排序,代码更简洁:
pipeline := mongo.Pipeline{ {{"$sort", bson.D{ {"$indexOfArray", bson.A{ bson.A{"IN_PROGRESS", "ON_DELIVERY", "DELIVERED"}, // 自定义排序顺序 "$status", }}, 1, // 升序排序,索引越小越靠前 }}}, } // 后续查询、解码逻辑与方案一一致
该方案适合排序规则固定且简单的场景,代码量更少。
内容的提问来源于stack exchange,提问作者Ayman Elmalah
相关产品推荐
相关产品推荐

