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

如何将指定SQL查询转换为Go语言中的MongoDB聚合查询

MySQL转MongoDB聚合查询解决方案

原SQL逻辑拆解

原SQL核心逻辑:

  • 筛选clientid = 12的记录
  • 按presenceid分组
  • 对每组计算:将datefinished(为空则用当前时间)与dateadded的时间差转成秒数,再求和

MongoDB聚合管道实现

对应的MongoDB聚合管道包含两个核心阶段:

db.userpresences.aggregate([
  {
    $match: { clientid: 12 }
  },
  {
    $group: {
      _id: "$presenceid",
      count: {
        $sum: {
          $divide: [
            {
              $subtract: [
                { $ifNull: ["$datefinished", "$$NOW"] },
                "$dateadded"
              ]
            },
            1000
          ]
        }
      }
    }
  }
])

逻辑对应说明:

  • $ifNull: ["$datefinished", "$$NOW"]:等价于SQL的IFNULL(userpresences.datefinished, NOW()),$$NOW是MongoDB聚合内置的当前时间变量
  • $subtract:替代SQL的TIMEDIFF,MongoDB中日期直接相减会得到毫秒级差值
  • $divide: [..., 1000]:将毫秒差值转换为秒数,对应SQL的TIME_TO_SEC
  • $sum:对每组的秒数差值求和,和SQL的SUM()功能完全一致

对应的Go代码实现

补充过滤阶段并修正分组计算逻辑,完整代码如下:

import (
	"context"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/bson"
)

func calculatePresenceDuration(collection *mongo.Collection, ctx context.Context) (*mongo.Cursor, error) {
	// 过滤阶段:对应SQL的WHERE clientid = 12
	matchStage := bson.D{{"$match", bson.D{{"clientid", 12}}}}

	// 分组计算阶段:实现SUM(...)的统计逻辑
	groupStage := bson.D{
		{"$group", bson.D{
			{"_id", "$presenceid"},
			{"count", bson.M{
				"$sum": bson.M{
					"$divide": []interface{}{
						bson.M{
							"$subtract": []interface{}{
								bson.M{"$ifNull": []interface{}{"$datefinished", "$$NOW"}},
								"$dateadded",
							},
						},
						1000,
					},
				},
			}},
		}},
	}

	// 执行聚合查询
	return collection.Aggregate(ctx, mongo.Pipeline{matchStage, groupStage})
}

代码说明:

  • 先通过$match过滤数据,减少分组计算的数据量,和SQL的WHERE作用一致
  • $$NOW在Go的BSON结构中直接以字符串传入,MongoDB会自动识别为内置变量
  • 用bson.M和bson.D嵌套构建聚合表达式,保证结构符合MongoDB的语法要求

内容的提问来源于stack exchange,提问作者Marko Mikulić

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 14:54:19