Go driver Use of undefined variable: this

Hello,
While trying to run the following query, it is working fine on mongo shell, but I have the following on my golang application:

Invalid $set :: caused by :: Use of undefined variable: this
db.getCollection('interests').aggregate([
  {
      $lookup:{
          from: "products",
          localField: "product_types.product_id",
          foreignField: "_id",
          as: "productInterestData"
      }
  },
  {
    $set: {
      "product_types": {
        $map: {
          input: "$product_types",
          in: {
            $mergeObjects: [
              "$$this",
              { product: {
                  $arrayElemAt: [
                    "$productInterestData",
                    {$indexOfArray: ["$productInterestData._id", "$$this.product_id"]}
                  ]
                }}
            ]
          }
        }
      }
    }
  }
])
pipeline := mongo.Pipeline{
    // join product model
    // lookup field
    bson.D{bson.E{Key: "$lookup", Value: bson.M{
        "from":         "products",
        "localField":   "product_types.product_id",
        "foreignField": "_id",
        "as":           "productInterestData",
    }}},
    // set array
    bson.D{bson.E{Key: "$set", Value: bson.E{
        Key: "product_types", Value: bson.E{
            Key: "$map", Value: bson.D{
                bson.E{Key: "input", Value: "$product_types"},
                bson.E{Key: "in", Value: bson.E{
                    Key: "$mergeObjects", Value: bson.A{
                        "$$this",
                        bson.E{Key: "product", Value: bson.E{Key: "$arrayElemAt", Value: bson.A{
                            "$productInterestData",
                            bson.E{Key: "$indexOfArray", Value: bson.A{"$productInterestData._id", "$$this.product_id"}},
                        }}},
                    },
                }},
            },
        },
    }}},
    // join data
    bson.D{bson.E{Key: "$unset", Value: "productInterestData"}},
}
cursor, err := ctx.Store.GetCollection(ctx, &models.Interest{}).Aggregate(c, pipeline)
		if err != nil {
			utils.Log(c, "warn", err)
			return
		}

Hey @chapad, thanks for the question! I think the issue may be related to using bson.E as the Value in another bson.E. Typically a bson.E should never be used as the Value in a bson.E because the generated BSON doesn’t have the expected structure.

For example, this part of your aggregation pipeline:

bson.D{bson.E{Key: "$set", Value: bson.E{
    Key: "product_types", Value: bson.E{
        Key: "$map", Value: bson.D{
            bson.E{Key: "input", Value: "$product_types"},
// ...

should be rewritten using a bson.D as the Values:

bson.D{
    bson.E{Key: "$set", Value: bson.D{
        bson.E{Key: "product_types", Value: bson.D{
            bson.E{Key: "$map", Value: bson.D{
                bson.E{Key: "input", Value: "$product_types"},
// ...

Recent versions of MongoDB Compass support exporting aggregation pipelines as Go-syntax BSON documents (see the aggregation Export to Language docs). That can be really helpful for translating complex aggregation pipelines that work in the MongoDB shell to Go-syntax aggregation pipelines. Check it out and see if it helps!

P.S. The top-level element for an “Export to Language” exported aggregation pipelines is a bson.A, but you can update that top-level bson.A to mongo.Pipeline to make it more readable.

3 Likes

Hello,
Thanks for the insight, it is very convenient to export directly from MongoDB Compass.
Unfortunately, even with the exported code, I still have the same issue (Invalid $set :: caused by :: Use of undefined variable: this).
Is it something unsupported by the mongo driver, and is it possible to investigate more, or open an issue on the driver?

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.