英文:
Blank data in query with aggregation only when querying with golang implementation
问题
我正在为您翻译以下内容:
我正在尝试使用聚合操作获取一个文档数组。聚合操作可以同时匹配一个聊天数组,按时间戳排序,然后按chat_id分组,只选择每个聊天中的最后一条消息。
所以我有一个包含三个chat_id的数组,我想获取具有这些chat_id的最后三条消息。
以下是两个示例:第一个是在控制台中的聚合操作和我得到的响应示例。第二个是golang中的一个变体,但输出中得到的是空对象。
第一个示例:
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} // 空数据
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
}
]
英文:
I'm trying to get an array of documents using aggregation. Aggregation to simultaneously match an array of chats, sort by timestamp, and then group by chat_id, selecting only the last message from each.
So I have an array of three chat_id and I want to get the last three messages that have that chat_id.
Below are two examples: The first is the aggregation in the console and an example of the response I get. The second is a variant in golang, but I get empty objects in the output
This is MongoDB playgroud work example
First example
db.message.aggregate([
{
$match: {
chat_id: {
$in: ["dtlzoD9fI15q8_YM6eqp", "unps_ZwBZ7mCubC3TsKl"],
},
}
},
{
$sort: {
"created": -1,
},
},
{
$group: {
"_id": {"chat_id": "$chat_id"},
"doc": { "$last": "$$ROOT" }
}
}
])
First response
[
{
"_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
}
}
]
Second example. This isn't work example
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
}
}()
Second Response
MSG: &{ 0} // empty data
MSG: &{ 0}
What I want to get out of aggregation
[
{
"_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
},
]
答案1
得分: 1
这个问题可能是因为你的消息模式不正确(注意你的 JS 聚合和 go 聚合之间有一个小差异,前者使用 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 MessageInner `json:"message" bson:"message"`
}
另一种方法是在最后使用 $replaceRoot
聚合阶段。
{ $replaceRoot: { newRoot: "$message" } }
英文:
This issue is probably because your message schema isn't correct (note there is a small difference between your JS aggregate and your go one in that use use doc
in the former and message
in the latter, I'll stick with 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"`
}
An alternate would be to use the $replaceRoot
aggregation stage at the end
{ $replaceRoot: { newRoot: "$message" } }
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论