MongoDB查询中sort()方法排序失效问题求助
问题分析与解决方案
首先明确一点:你的MongoDB排序操作其实已经生效了,问题出在后续的日期输出逻辑上,导致结果不符合预期。
为什么当前输出不符合期望?
拆解下你的代码逻辑就能找到原因:
- 数据库里的两个
Schedule文档start_date完全相同,所以Sort("start_date")已经把它们排在一起了(字段值相同时,顺序默认是文档插入顺序)。 - 你在
GetSchedule函数里是先遍历第一个文档,生成它的所有目标日期并逐个打印;再遍历第二个文档,重复同样的打印操作。 - 这就导致输出是「第一组4个日期 + 第二组4个日期」,而不是你想要的「每个日期连续出现两次」。
怎么修改才能得到期望输出?
你需要把输出逻辑从「按文档遍历打印」改成「按日期遍历,每个日期打印对应文档的次数」。这里提供两种简单的实现方式:
方式1:先收集所有唯一日期,再按日期打印
import "sort" import "net/http" func GetSchedule(c *gin.Context) { selected_day := "Monday" conditions := bson.M{"day": selected_day} data, err := models.GetSchedulingListing(conditions) if err != nil { // 记得处理错误,返回给客户端提示 c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } // 第一步:收集所有需要打印的唯一日期 dateSet := make(map[int64]bool) var sortedDates []int64 for _, item := range data { currentDate := item.StartDate endDate := item.EndDate days := int(time.Unix(endDate, 0).Sub(time.Unix(currentDate, 0)).Hours() / 24) + 1 for i := 0; i < days; i++ { if time.Unix(currentDate, 0).Weekday().String() == selected_day { if !dateSet[currentDate] { dateSet[currentDate] = true sortedDates = append(sortedDates, currentDate) } } currentDate += 86400 } } // 确保日期按升序排列 sort.Slice(sortedDates, func(i, j int) bool { return sortedDates[i] < sortedDates[j] }) // 第二步:遍历每个日期,打印对应文档的次数 for _, date := range sortedDates { for range data { fmt.Println(date) } } }
方式2:利用所有文档日期序列相同的特性简化代码
因为你的两个Schedule文档start_date和end_date完全一致,所以可以直接从第一个文档获取日期序列,然后每个日期打印两次:
import "net/http" func GetSchedule(c *gin.Context) { selected_day := "Monday" conditions := bson.M{"day": selected_day} data, err := models.GetSchedulingListing(conditions) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } if len(data) == 0 { return } // 从第一个文档获取目标日期序列 var dates []int64 item := data[0] currentDate := item.StartDate endDate := item.EndDate days := int(time.Unix(endDate, 0).Sub(time.Unix(currentDate, 0)).Hours() / 24) + 1 for i := 0; i < days; i++ { if time.Unix(currentDate, 0).Weekday().String() == selected_day { dates = append(dates, currentDate) } currentDate += 86400 } // 每个日期打印对应文档的次数 for _, date := range dates { for range data { fmt.Println(date) } } }
额外提示
- 你的
Select操作排除了StartTime和EndTime字段,所以返回的data里这两个字段值为0,不过这对你当前的日期打印逻辑没有影响。 - 数据库操作一定要处理错误,避免程序panic或者静默失败。
内容的提问来源于stack exchange,提问作者gourav
相关产品推荐
相关产品推荐

