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

MongoDB查询中sort()方法排序失效问题求助

问题分析与解决方案

首先明确一点:你的MongoDB排序操作其实已经生效了,问题出在后续的日期输出逻辑上,导致结果不符合预期。

为什么当前输出不符合期望?

拆解下你的代码逻辑就能找到原因:

  1. 数据库里的两个Schedule文档start_date完全相同,所以Sort("start_date")已经把它们排在一起了(字段值相同时,顺序默认是文档插入顺序)。
  2. 你在GetSchedule函数里是先遍历第一个文档,生成它的所有目标日期并逐个打印;再遍历第二个文档,重复同样的打印操作。
  3. 这就导致输出是「第一组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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:27:32