如何在mongo-go-driver中使用“Let”聚合选项?

huangapple go评论84阅读模式
英文:

How to use “Let” Aggregate options in mongo-go-driver?

问题

尝试在聚合选项中使用mongo-go-driver的SetLet,将之前在函数中定义的用户变量传递到聚合管道中。

我试图解析文档来实现这个功能...

SetLet只需要一个interface{}类型的输入参数。

我正在使用正确格式的管道聚合,其中我希望SetLet会填充"$$variableName"。

我尝试了传递bson.Mmap[string]interface{},但这两种方式都没有成功(聚合没有返回任何文档)。

有人成功使用mongo-go-driver中的SetLet吗?能否给出一个正确使用它的示例?

基本代码示例:

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() {
	// 我将连接到一个实际的Mongo数据库并获取一个实际的集合,但这里只是示例
	var col mongo.Collection

	// 我想通过"Let"在我的管道中设置的变量
	externalId := "test"
	let := bson.M{"externalId": externalId}
	options := options.Aggregate().SetLet(let)

	// 管道聚合,我希望我的外部变量取代"$$externalId"
	aggregation := bson.A{bson.D{{"$match", bson.D{{"id", "$$externalId"}}}}}

	// 执行聚合并存储结果(结果将为空,因为没有返回任何文档,因为$match没有起作用)
	cursor, _ := col.Aggregate(context.TODO(), aggregation, options)
	var result any
	cursor.All(context.TODO(), &result)
}

希望对你有所帮助!

英文:

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

答案1

得分: 2

搞定了。我对SetLet的使用是正确的。问题在于似乎我不能直接在$match管道阶段中使用用户定义的变量。我需要使用$expr来正确使用我的用户变量。

bson.D{
    {"$match",
        bson.D{
            {"$expr",
                bson.D{
                    {"$eq",
                        bson.A{
                            "$id",
                            "$$externalId",
                        },
                    },
                },
            },
        },
    },
}
英文:

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.

bson.D{
			{"$match",
				bson.D{
					{"$expr",
						bson.D{
							{"$eq",
								bson.A{
									"$id",
									"$$externalId",
								},
							},
						},
					},
				},
			},
		}

答案2

得分: 0

@Tyler的答案关于使用$expr操作符是正确的。这是官方文档中关于let选项的说明:

要在管道的$match阶段中使用变量进行结果过滤,必须在$expr操作符内访问该变量。

请参阅在let中使用变量

使用bson.D会导致代码难看。最好使用bson.M

aggregation := bson.A{
	bson.M{
		"$match": bson.M{
			"$expr": bson.M{
				"$eq": bson.A{"$id", "$$externalId"},
			},
		},
	},
}
英文:

@Tyler's answer is correct about the using of $expr operator. Here is the note from the official documentation for the let option:

> To filter results using a variable in a pipeline $match stage, you must access the variable within the $expr operator.

See Use Variables in let.

The use of bson.D results in ugly code. It's better to use bson.M:

aggregation := bson.A{
	bson.M{
		"$match": bson.M{
			"$expr": bson.M{
				"$eq": bson.A{"$id", "$$externalId"},
			},
		},
	},
}

huangapple
  • 本文由 发表于 2023年6月30日 00:15:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/76582866.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定