我正在尝试使用聚合来获取文档数组。聚合以同时匹配聊天数组,按时间戳排序,然后按 chat_id 分组,仅选择每个聊天中的最后一条消息。 所以我有一个包含三个 chat_id 的数组,我想获取具有该 chat_id 的最后三条消息。
下面是两个示例:第一个是控制台中的聚合以及我得到的响应的示例。第二个是 golang 中的变体,但我在输出中得到空对象
这是 mongodb playground 工作示例
第一个示例
db.message.aggregate([ { $match: { chat_id: { $in: ["dtlzod9fi15q8_ym6eqp", "unps_zwbz7mcubc3tskl"], }, } }, { $sort: { "created": -1, }, }, { $group: { "_id": {"chat_id": "$chat_id"}, "doc": { "$last": "$$root" } } } ])
第一响应
[ { "_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 } }()
第二个响应
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 one 之间存在细微差别,前者使用 doc
,后者使用 message
,我将坚持使用 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" } }