I have two MongoDB collections, one users and another for accesskeys. I want to get an aggregation of the users together with their accesskeys depending on whether they are subscribed to a specific channel or not. However when I run the code, the cursor data has the user data but the variable containing the lookup array is missing. The pipeline syntax is however working fine on mongodb-compass.
Data
Users Collection Sample
id: 42069
displayName: "tiredApe"
subscribedChannel: "BananaClips"
AccessKeys Collection Sample
userId: 42069"
apiKey: "yadayadayada"
Code
pipeline := `[
{
'$match': {
'subscribedChannel': 'BananaClips'
}
},
{
'$lookup': {
'from': 'accesskeys',
'let': {
'searchId': {
'$toString': '$id'
}
},
'pipeline': [
{
'$match': {
'$expr': {
'$eq': [
'$userId', '$$searchId'
]
}
}
}
],
'as': 'accesskeys'
}
},
{
'$unwind': {
'path': '$accesskeys'
}
}
]`
var err error
var cur *mongo.Cursor
var doc bson.M
opts := options.Aggregate()
opts.SetAllowDiskUse(true)
opts.SetBatchSize(15)
if cur, err = userCollection.Aggregate(ctx, MongoPipeline(pipeline), opts); err != nil {
panic(err)
}
defer cur.Close(ctx)
for cur.Next(ctx) {
fmt.Println(cur.Current.String())
}
Helper function to convert the Pipeline string to a mongo.Pipeline object :
func MongoPipeline(str string) mongo.Pipeline {
var pipeline = []bson.D{}
str = strings.TrimSpace(str)
if strings.Index(str, "[") != 0 {
var doc bson.D
bson.UnmarshalExtJSON([]byte(str), false, &doc)
pipeline = append(pipeline, doc)
} else {
bson.UnmarshalExtJSON([]byte(str), false, &pipeline)
}
return pipeline
}
The expected result (as evidenced from the many trial on mongodb-compass) :
{
id: 42069,
displayName: "tiredApe",
subscribedChannel: "BananaClips",
accesskeys: {
userId: 42069,
apiKey: "yadayadayada"
}
}
The current result from Golang :
{
id: 42069,
displayName: "tiredApe",
subscribedChannel: "BananaClips"
}
Really looking for a breakthrough. Been stuck at it for half a day and can't figure out what I am missing or why the accesskey variable is missing from the result. Thanks in advance.