gpt4 book ai didi

mongodb - 通过引用父文档中的多个值来使用 $lookup

转载 作者:行者123 更新时间:2023-12-05 05:20:12 26 4
gpt4 key购买 nike

我正在尝试 MongoDb 3.5.8 中可用的新 $lookup pipeline 功能,想知道如何从 pipeline< 引用父文档中的字段.

我试图将父文档中的两个字段与查找文档中的两个字段进行比较。不确定如何执行此操作 {$eq : ['$input_doc.field1', '$field1'] }

 db.input_doc.aggregate([
{
$lookup:
{
from: "foreign_doc",
pipeline: [
{ $project: { 'matched': { $and : [
{ $eq : ["$input_doc.field1", "$field1"] },
{ $eq : ["$input_doc.field2", "$field2"] }
]} },
{ $match : { 'matched' : true } }
],
as: "as_doc"
}
}
])

谢谢

最佳答案

您在这里的意思不是很清楚,您可能是指将 let 与新的 pipeline 选项一起使用,但也可能是指完全不同的情况。

pipeline 操作通常用于“非相关”数据检索,这在各种用例中都很有用。这与“相关”数据相反,其中 localFieldforeignField 可以应用于两个集合之间的“连接”。

如前所述,这包含在 DOCS-10298

最好作为示例进行演示。创建这些集合:

db.related.insert([
{ "a": 1, "b": 2 },
{ "a": 2, "b": 2 },
{ "a": 3, "b": 3 }
])

db.parent.insert({
"name": "test",
"b": 2
})

我可以在这里使用 pipelinelet 语句来测试另一个集合的项目的逻辑条件,如下所示:

db.parent.aggregate([
{ "$lookup": {
"from": "related",
"let": {
"b": "$b"
},
"pipeline": [
{ "$addFields": {
"matched": { "$eq": [ "$$b", "$b" ] }
}}
],
"as": "results"
}}
])

这将给出结果:

{
"_id" : ObjectId("595332c28965d862ce61f451"),
"name" : "test",
"b" : 2,
"results" : [
{
"_id" : ObjectId("59532b028965d862ce61f44d"),
"a" : 1,
"b" : 2,
"matched" : true
},
{
"_id" : ObjectId("59532b028965d862ce61f44e"),
"a" : 2,
"b" : 2,
"matched" : true
},
{
"_id" : ObjectId("59532b028965d862ce61f44f"),
"a" : 3,
"b" : 3,
"matched" : false
}
]
}

这表明条件是根据父文档中 let 中声明的变量与在提供的 pipeline 中测试的相关集合中的变量进行测试的。

这还允许您使用“逻辑”过滤器,例如 $redact :

db.parent.aggregate([
{ "$lookup": {
"from": "related",
"let": {
"b": "$b"
},
"pipeline": [
{ "$redact": {
"$cond": {
"if": { "$eq": [ "$$b", "$b" ] },
"then": "$$KEEP",
"else": "$$PRUNE"
}
}}
],
"as": "results"
}}
])

哪个返回:

{
"_id" : ObjectId("595332c28965d862ce61f451"),
"name" : "test",
"b" : 2,
"results" : [
{
"_id" : ObjectId("59532b028965d862ce61f44d"),
"a" : 1,
"b" : 2
},
{
"_id" : ObjectId("59532b028965d862ce61f44e"),
"a" : 2,
"b" : 2
}
]
}

当然,这已经包含在 MongoDB 3.2 中引入的现有功能以及正常的“相关”选项中:

db.parent.aggregate([
{ "$lookup": {
"from": "related",
"localField": "b",
"foreignField": "b",
"as": "results"
}}
])

结果同上。

当然,如果你想要“附加条件”,那么使用 $unwind 编写实际上是最有效的和 $match :

db.parent.aggregate([
{ "$lookup": {
"from": "related",
"localField": "b",
"foreignField": "b",
"as": "results"
}},
{ "$unwind": "$results" },
{ "$match": { "results.a": 1 } }
])

这是因为 $lookup 之后以下阶段的聚合管道选项实际上被“吊”进了$lookup操作本身。在“解释”输出中展示:

    {
"$lookup" : {
"from" : "related",
"as" : "results",
"localField" : "b",
"foreignField" : "b",
"unwinding" : {
"preserveNullAndEmptyArrays" : false
},
"matching" : {
"a" : {
"$eq" : 1
}
}
}
}

这表明在 $lookup 中实际应用了“unwinding”和“matching”选项。 .到目前为止,您还不能直接编写它,但管道组合应用了这种行为。

这实际上是为了处理 BSON 限制不会因创建包含超过 16MB 上限的条目的数组而被打破。

简而言之,在大多数情况下,您通常需要现有行为而不需要新选项。然而。

关于mongodb - 通过引用父文档中的多个值来使用 $lookup,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44793414/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com