英文:
How to use “Let” Aggregate options in mongo-go-driver?
问题
尝试在聚合选项中使用mongo-go-driver的SetLet
,将之前在函数中定义的用户变量传递到聚合管道中。
我试图解析文档来实现这个功能...
SetLet
只需要一个interface{}
类型的输入参数。
我正在使用正确格式的管道聚合,其中我希望SetLet
会填充"$$variableName"。
我尝试了传递bson.M
和map[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"},
},
},
},
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论