Trying to use mongo-go-driver SetLet
in the aggregate options to pass user variables defined earlier in my function into my aggregation pipeline.
Trying to parse the documentation for this…
SetLet
asks for just an interface{}
for the input parameter.
I’m using a correctly formatted pipeline aggregation using “$$variableName” where I’m hoping the SetLet
will fill in.
I’ve tried passing in a bson.M
and a map[string]interface{}
but neither of these result in a successful pass through for me (aggregation returns no documents).
Has anyone successfully used SetLet
in mongo-go-driver
and has a working example of how to use it properly?
Basic code example:
package test
import (
"context"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
func test() {
// I would connect to an actual mongo database and get an actual collection, but I won't for example
var col mongo.Collection
// the variable I want to set via "Let" in my pipeline
externalId := "test"
let := bson.M{"externalId": externalId}
options := options.Aggregate().SetLet(let)
// The pipeline aggregation, I want my external variable to take place of "$$externalId"
aggregation := bson.A{bson.D{{"$match", bson.D{{"id", "$$externalId"}}}}}
// Perform aggregation and store result (Result will be empty because no documents were returned, because $match did not work)
cursor, _ := col.Aggregate(context.TODO(), aggregation, options)
var result any
cursor.All(context.TODO(), &result)
}
2
Answers
Figured it out. My usage of
SetLet
was correct. The problem was that it seems like I cannot use a user defined variable directly in my$match
pipeline stage. I need to use $expr in order to properly use my user var.@Tyler’s answer is correct about the using of
$expr
operator. Here is the note from the official documentation for thelet
option:See Use Variables in let.
The use of
bson.D
results in ugly code. It’s better to usebson.M
: