alex
alex

Reputation: 608

Blank data in query with aggregation only when querying with golang implementation

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
  },
]

Upvotes: 2

Views: 160

Answers (1)

Zack Newsham
Zack Newsham

Reputation: 3002

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" } }

Upvotes: 1

Related Questions