mongodb - 仅在使用 golang 实现查询时使用聚合查询中的空白数据

标签 mongodb go

我正在尝试使用聚合获取一组文档。聚合以同时匹配一组聊天,按时间戳排序,然后按 chat_id 分组,只选择每个聊天的最后一条消息。 所以我有一个包含三个 chat_id 的数组,我想获取具有该 chat_id 的最后三条消息。

下面是两个示例:第一个是控制台中的聚合和我得到的响应示例。第二个是 golang 中的变体,但我在输出中得到空对象

这是 MongoDB playgroud work example

第一个例子

db.message.aggregate([
    {
        $match: {
            chat_id: {
                $in: ["dtlzoD9fI15q8_YM6eqp", "unps_ZwBZ7mCubC3TsKl"],
            },
        }
    },
    {
        $sort: {
            "created": -1,
        },
    },
    {
        $group: {
            "_id": {"chat_id": "$chat_id"},
            "doc": { "$last": "$$ROOT" }
        }
    }
])

第一 react

[
  {
    "_id": {
      "chat_id": "unps_ZwBZ7mCubC3TsKl"
    },
    "doc": {
      "_id": {"$oid": "63ac61d71a11d3b05340c001"},
      "id": "wsBFKoN51q5v4Nnv3A-B",
      "chat_id": "unps_ZwBZ7mCubC3TsKl",
      "body": "Certainty determine at of arranging perceived situation or. Or wholly pretty county in oppose. Favour met itself wanted settle put garret twenty. In astonished apartments resolution so an it. Unsatiable on by contrasted to reasonable companions an. On otherwise no admitting to suspicion furniture it. ",
      "created": 1672241623466
    }
  },
  {
    "_id": {
      "chat_id": "dtlzoD9fI15q8_YM6eqp"
    },
    "doc": {
      "_id": {"$oid": "63ac607f141f0526cba7113d"},
      "id": "jhjVxQUzQbPCLebnupS9",
      "chat_id": "dtlzoD9fI15q8_YM6eqp",
      "body": "Certainty determine at of arranging perceived situation or. Or wholly pretty county in oppose. Favour met itself wanted settle put garret twenty. In astonished apartments resolution so an it. Unsatiable on by contrasted to reasonable companions an. On otherwise no admitting to suspicion furniture it. ",
      "created": 1672241279354
    }
  }
]

第二个例子。这不是工作示例

type Message struct {
    ID      string `json:"id" bson:"id"`
    ChatID  string `json:"chat_id" bson:"chat_id"`
    Body    string `json:"body" bson:"body"`
    Created int64  `json:"created" bson:"created"`
}

...
ids := []string{"unps_ZwBZ7mCubC3TsKl", "dtlzoD9fI15q8_YM6eqp"}
matchStage := bson.D{{
    Key: "$match", Value: bson.D{{Key: "chat_id", Value: bson.D{{Key: "$in", Value: ids}}}},
}}
sortStage := bson.D{{"$sort", bson.D{{"created", -1}}}}
groupStage := bson.D{{
    Key: "$group", Value: bson.D{
        {
            Key: "_id", Value: bson.D{
                {"chat_id", "$chat_id"},
            },
        },
        {
            Key: "message", Value: bson.D{
                {"$last", "$$ROOT"},
            },
        },
    },
}}

cursor, err := db.Aggregate(context.Background(), mongo.Pipeline{matchStage, groupStage, sortStage})

if err != nil {}

var messages []*Message
err = cursor.All(context.Background(), &messages)
if err != nil {
    fmt.Print("Cursor err: ", err)
    return
}

defer func() {
    err := cursor.Close(context.Background())
    if err != nil {
        return
    }
}()

第二 react

MSG: &{   0} // empty data
MSG: &{   0}

我想从聚合中得到什么

[
  {
    "_id": {"$oid": "63ac607f141f0526cba7113d"},
    "id": "jhjVxQUzQbPCLebnupS9",
    "chat_id": "dtlzoD9fI15q8_YM6eqp",
    "body": "Certainty determine at of arranging perceived situation or. Or wholly pretty county in oppose. Favour met itself wanted settle put garret twenty. In astonished apartments resolution so an it. Unsatiable on by contrasted to reasonable companions an. On otherwise no admitting to suspicion furniture it. ",
    "created": 1672241279354
  },
  {
    "_id": {"$oid": "63ac61d71a11d3b05340c001"},
    "id": "wsBFKoN51q5v4Nnv3A-B",
    "chat_id": "unps_ZwBZ7mCubC3TsKl",
    "body": "Certainty determine at of arranging perceived situation or. Or wholly pretty county in oppose. Favour met itself wanted settle put garret twenty. In astonished apartments resolution so an it. Unsatiable on by contrasted to reasonable companions an. On otherwise no admitting to suspicion furniture it. ",
    "created": 1672241623466
  },
]

最佳答案

这个问题可能是因为你的消息模式不正确(注意你的 JS 聚合和你的 go 之间有一个小的区别,在前者和 message 中使用 doc 在后者中,我将坚持使用 message

type MessageInner struct {
    ID      string `json:"id" bson:"id"`
    ChatID  string `json:"chat_id" bson:"chat_id"`
    Body    string `json:"body" bson:"body"`
    Created int64  `json:"created" bson:"created"`
}

type Message struct {
    MessageInner Doc `json:"message" bson:"message"`
}

另一种方法是在最后使用 $replaceRoot 聚合阶段

{ $replaceRoot: { newRoot: "$message" } }

关于mongodb - 仅在使用 golang 实现查询时使用聚合查询中的空白数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74952891/

相关文章:

javascript - Node.js/MongoDB : How can I use module. 导出以将 localhost 数据库 url 传递给 server.js 文件?

php - MongoDB 和 PHP 库游标超时

google-app-engine - Golang 应用引擎的 git 推送和部署

mysql - Go Template 循环(范围)出评论

go - 如何自己产生熵? - RSA Golang

node.js - mongodb、node.js 和加密数据

Mongodb查询从多个键中选择记录

python - Pymongo $push 不更新数组,也不异常(exception)

go - 如何编写干净的集成测试

concurrency - 使用固定数量的工作人员处理永无休止的队列中的作业