Mongo 如何使用 DBRef 进行 $lookup

2023-11-30

我有麻烦了(/(ㄒoㄒ)/~~)。假设集合A是

{ 
    "_id" : ObjectId("582abcd85d2dfa67f44127e1"), 
    "bid" : [
        DBRef("B", ObjectId("582abcd85d2dfa67f44127e0")),
        DBRef("B", ObjectId("582abcd85d2dfa67f44127e1"))
    ]
}


和集合B:

{ 
    "_id" : ObjectId("582abcd85d2dfa67f44127e0"),  
    "status" : NumberInt(1), 
    "seq" : NumberInt(0)
},
{ 
    "_id" : ObjectId("582abcd85d2dfa67f44127e1"), 
    "status" : NumberInt(1), 
    "seq" : NumberInt(0)
} 


我不知道如何$查找“出价”。我试过

db.A.aggregate(
    [
        {$unwind: {path: "$bid"}},
        {$lookup: {from: "B", localField: "bid", foreignField: "_id", as: "bs"}},
    ]
) 


and

db.A.aggregate(
    [
        {$unwind: {path: "$bid"}},
        {$lookup: {from: "B", localField: "bid.$id", foreignField: "_id", as: "bs"}},
    ]
)


但它不起作用。有人可以帮忙吗?谢谢。


事实上,另一个答案是错误的。可以在聚合器中对 DBref 字段进行查找,并且不需要使用 mapreduce。

Solution

db.A.aggregate([
{
    $project: { 
        B_fk: {
          $map: { 
             input: { 
                  $map: {
                      input:"$bid",
                      in: {
                           $arrayElemAt: [{$objectToArray: "$$this"}, 1]
                      },
                  }
             },
             in: "$$this.v"}},
        }
}, 
{
    $lookup: {
        from:"B", 
        localField:"B_fk",
        foreignField:"_id", 
        as:"B"
    }
}
])

result

{
    "_id" : ObjectId("59bb79df1e9c00162566f581"),
    "B_fk" : null,
    "B" : [ ]
},
{
    "_id" : ObjectId("582abcd85d2dfa67f44127e1"),
    "B_fk" : [
        ObjectId("582abcd85d2dfa67f44127e0"),
        ObjectId("582abcd85d2dfa67f44127e1")
    ],
    "B" : [
        {
            "_id" : ObjectId("582abcd85d2dfa67f44127e0"),
            "status" : NumberInt("1"),
            "seq" : NumberInt("0")
        }
    ]
}

简短说明

使用 $map 循环遍历 DBRef,将每个 DBref 分解为一个数组,仅保留 $id 字段,然后使用 $$this.v 摆脱 k:v 格式,仅保留 ObjectId 并删除所有其余内容。您现在可以查找 ObjectId。

分步说明

在聚合器中,DBRef BSON 类型可以像对象一样处理,具有两个或三个字段(ref、id 和 db)。

如果你这样做:

db.A.aggregate([
    {
        $project: { 
            First_DBref_as_array: {$objectToArray:{$arrayElemAt:["$bid",0]}},
            Second_DBref_as_array: {$objectToArray:{$arrayElemAt:["$bid",1]}},
            }

    },

])

这是结果:

{
"_id" : ObjectId("582abcd85d2dfa67f44127e1"),
"First_DBref_as_array : [
    {
        "k" : "$ref",
        "v" : "B"
    },
    {
        "k" : "$id",
        "v" : ObjectId("582abcd85d2dfa67f44127e0")
    }
],
"Second_DBref_as_array" : [
    {
        "k" : "$ref",
        "v" : "B"
    },
    {
        "k" : "$id",
        "v" : ObjectId("582abcd85d2dfa67f44127e0")
    }
]
}

将 dbref 转换为数组后,您可以通过仅查询索引 1 处的值来摆脱无用的字段,如下所示:

db.A.aggregate([
    {
        $project: { 
            First_DBref_as_array: {$arrayElemAt: [{$objectToArray:{$arrayElemAt:["$bid",0]}},1]},
            Second_DBref_as_array: {$arrayElemAt: [{$objectToArray:{$arrayElemAt:["$bid",0]}},1]},
            }

    },

])

result:

{
    "_id" : ObjectId("582abcd85d2dfa67f44127e1"),
    "First_DBref_as_array" : {
        "k" : "$id",
        "v" : ObjectId("582abcd85d2dfa67f44127e0")
    },
    "Second_DBref_as_array" : {
        "k" : "$id",
        "v" : ObjectId("582abcd85d2dfa67f44127e0")
    }
}

然后你可以通过指向“$myvalue.v”最终得到你想要的值,就像这样

db.A.aggregate([
    {
        $project: { 
            first_DBref_as_array: {$arrayElemAt: [{$objectToArray:{$arrayElemAt:["$bid",0]}},1]},
            second_DBref_as_array: {$arrayElemAt: [{$objectToArray:{$arrayElemAt:["$bid",0]}},1]},
            }

    },
    {
        $project: {
            first_DBref_as_ObjectId: "$first_DBref_as_array.v",
            second_DBref_as_ObjectId: "$second_DBref_as_array.v"
        }
    }

])

result:

{
    "_id" : ObjectId("582abcd85d2dfa67f44127e1"),
    "first_DBref_as_ObjectId" : ObjectId("582abcd85d2dfa67f44127e0"),
    "second_DBref_as_ObjectId" : ObjectId("582abcd85d2dfa67f44127e0")
}

显然,在正常的管道中,您不需要所有这些冗余步骤,使用嵌套的 $map,您可以一次性获得相同的结果:

db.A.aggregate([
    {
        $project: { 
            B_fk: { $map : {input: { $map: {    input:"$bid",
                                    in: { $arrayElemAt: [{$objectToArray: "$$this"}, 1 ]}, } },
                            in: "$$this.v"}},

            }
    }, 

])

result:

{
    "_id" : ObjectId("582abcd85d2dfa67f44127e1"),
    "B_fk" : [
        ObjectId("582abcd85d2dfa67f44127e0"),
        ObjectId("582abcd85d2dfa67f44127e1")
    ]
}

我希望解释足够清楚,如果不清楚,请随时询问。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Mongo 如何使用 DBRef 进行 $lookup 的相关文章

随机推荐

  • python如何更改嵌套列表中的元素[重复]

    这个问题在这里已经有答案了 我已经使用Python很多次了 今天我对一个简单的嵌套列表感到惊讶 如何更改列表中元素的值 gt gt gt l 0 0 10 gt gt gt l 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  • Matplotlib 在阶梯图中仅绘制水平线

    我正在使用 matplotlib 从数据框中绘制一些步骤函数 df s1 plot c b drawstyle steps post df s2 plot c b drawstyle steps post 结果看起来像 我希望只绘制水平线
  • 如何从 PowerShell 调用复杂的 COM 方法?

    是否可以使用命名参数从 PowerShell 调用 COM 方法 我正在使用的 COM 对象方法有数十个参数 object GridData DataFile xCol yCol zCol ExclusionFilter DupMethod
  • 使用 Break 和 continue 语句的 While 循环

    我是初学者 while 语句中的break 和 continue 语句用于什么 while break continue 这两个关键字可以循环使用来改变它的行为方式 Break 语句终止循环并继续执行下一个可执行语句 continue 语句
  • 如何删除仅包含 NA 的列?

    我有一个 data frame 其中包含一些具有所有 NA 值的列 如何从 data frame 中删除它们 我可以使用该功能吗 na omit 指定一些额外的参数 一种方法是 df colSums is na df nrow df 如果一
  • C# - For 循环和 lambda 表达式

    我的问题是为什么我在 lambda 表达式中使用迭代器变量会得到错误的结果 好吧 我已经关注了 SWeko 的回答here 但这对我不起作用 这是我的伪代码 List
  • Odoo 在树视图第二行记录上抛出 MissingError

    我如何解决此错误 Odoo 在单击 TreeView 第二行按钮时抛出 MissingError 第一个记录行有效 但我需要这样 对于树上的每个记录 下面的代码将能够传递上下文并打开适当的视图 请协助 这是按钮上调用的代码 api mult
  • 绘制彼此靠近的对象[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 我想在屏幕上绘制下图 sphere cylinder angle 45 cyli
  • datetimepicker getDate 返回 UTC 格式的日期/时间

    我碰巧读到了这篇文章日期时间选择器插件并发现它很有用 我使用此工具面临的问题是我无法获取 UTC 或其他格式的数据 时间格式 我的目的是至少获取 UTC 格式的日期 时间 starttime datetimepicker ampm true
  • FluentNHibernate:使用 NotFound.Ignore() 映射引用时的性能损失

    我使用 FluentNhibernate 并且当关联引用映射为 NHibernate 时 我看到 NHibernate 执行许多查询NotFound Ignore 由于我的遗留数据库的引用完整性有点糟糕 我想知道是否有解决方法或者是否有我可
    1. /

    我有这种 xml 在哪里some li tags没有 ol ul 因为它是父级 需要添加为父级 Example ul ol li
  • GCP云函数实例生命周期

    我在 AWS 环境中工作了 4 年 主要使用 Lambda 根据我的经验 我知道 Lambda 函数的 实例 将存活大约 2 小时 现在我要为一个使用 GCP 及其云功能的项目工作 是否有关于 CF 实例 的生存时间的信息 我通常需要知道这
  • 在线程内使用全局字典

    假设我有一个Dictionary
  • 将自定义对象绑定到 JMS MapMessage

    是否有一种标准方法可以将我自己的自定义对象添加到 Map 然后将其正确编组到 MapMessage 中 目前我收到无效的对象类型消息 我注意到WebSphere有一个解决方案 但我正在寻找一些不绑定到特定AS的东西 如果没有这样的方法 也许
  • 如何将库添加到 Eclipse 项目

    我正在尝试向 Eclipse Galileo 添加一个库 但没有成功 库 gdi32 lib gt 在 MinGW 中 libgdi32 a 无论我尝试什么 它都不起作用 谁能准确地告诉我要在哪里输入什么才能完成此任务 Details 我有
  • 输入表单属性可以指定多个表单ID吗?或不? [复制]

    这个问题在这里已经有答案了 w3学校指定 定义和用法 form属性指定一个or more形成元素所属的形式 在http www w3schools com tags att input form asp 和 提示 要引用多种形式 使用空格分
  • 如何用循环绑定多个数据帧?

    我有 105 个带有 xts zoo class 的数据框 我想将它们的第 6 列合并到一个数据框中 因此 我创建了一个包含所有数据框名称的数据框 以便将其与 for 函数一起使用 mydata lt AAL for i in 2 105
  • Amazon S3 和 jqueryfileupload 插件的图像上传性能问题

    我在亚马逊上还有另一个问题 它与文件上传有关 我正在使用jquery文件上传和amazon API上传文件到amazon S3 我已经成功上传了 但是涉及到一个技巧 我必须将图像存储在我的服务器上 然后使用以下命令将其从那里移动到 S3pu
  • ANTLR PCRE 语法到 JS 目标

    我正在尝试构建 Bart Kiers 的 ANTLR PCRE 语法 请参阅 http big o nl apps pcreparser pcre PCREParser html 到 JS 目标 我构建它的唯一方法是使用全局回溯和记忆 它生
  • Mongo 如何使用 DBRef 进行 $lookup

    我有麻烦了 o 假设集合A是 id ObjectId 582abcd85d2dfa67f44127e1 bid DBRef B ObjectId 582abcd85d2dfa67f44127e0 DBRef B ObjectId 582ab