【问题标题】:Native MongoDB query joining 2 tables using ObjectID as foreign field本机 MongoDB 查询使用 ObjectID 作为外部字段连接 2 个表
【发布时间】:2020-08-30 07:16:19
【问题描述】:

我有一个不是我创建的 mongo 数据库,但需要从中提取一些额外的数据。我可以访问数据库,并且可以查看和查询表,但是我无法连接两个表以在查询输出中提供所有必要的信息。

我有 2 个我感兴趣的表。第一个设置,它的文档看起来像这样(截断):

{
   "_id" : ObjectId("5aff382669153dc20edf945a"),
   "key" : "mgmt",
   "site_id" : "5aff382669153dc20edf9456",
   "advanced_feature_enabled" : false,
   "auto_upgrade" : true
}

和网站,看起来像这样(截断):

{
   "_id" : ObjectId("5aff382669153dc20edf9456"),
   "desc" : "Joe's Crab Shack",
}

setting 表中的site_id 是一个外键,它引用site 表中的十六进制组件_id。 我希望输出类似于此,但我没有成功:

{
"_id" : ObjectId("5aff382669153dc20edf9456"),
"desc" : "Joe's Crab Shack",
"setting" : [
                "_id" : ObjectId("5aff382669153dc20edf945a"),
                "key" : "mgmt",
                "site_id" : "5aff382669153dc20edf9456",
                "advanced_feature_enabled" : false,
                "auto_upgrade" : true
            ]
}

我希望能够只进行数据库查询,目前使用的是 Robo 3T,而不必求助于脚本或编程。我能够达到预期结果的最接近的结果如下。此查询返回 site 文档,以及所有没有 site_id 外键的 setting 文档。

db.site.aggregate([
{
    $lookup:
    {
        from: "setting",
        localField:"_id.str",
        foreignField:"site_id",
        as: "setting"
    }
}
])

我确定我遗漏了一些简单的东西,但我对 MongoDB 很陌生,并且由于 SQL 和 Mongo 之间的术语差异而有点迷茫。对于任何想知道的人,数据库实际上是大型多站点 Ubiquiti 控制器的后端,我希望创建“报告”,为需要升级的设备提供更多洞察,哪些设置不符合我们的“默认”配置等

【问题讨论】:

    标签: mongodb mongodb-query robo3t


    【解决方案1】:

    如果setting集合中的site_idObjectId类型,那么你可以试试这个

    db.site.aggregate([
      {
        $lookup: {
          from: "setting",
          localField: "_id",
          foreignField: "site_id",
          as: "setting"
        }
      }
    ])
    

    你可以在这里测试它Mongo Playground

    如果site_id 的类型为string,则您无法进行该查找,因为_idsite_id 的类型也应匹配(ObjectIds),因此您可以更改setting 架构制作ObjectId 类型的site_id 并引用site 架构

    而不是这个

    site_id: String
    

    使用这个

    site_id: { type: ObjectId, ref: 'site' }
    

    更新

    如果 site_id 是一个字符串并且您无法更改设置架构,那么我们可以做一些工作

    我们可以在聚合管道中为站点文档添加一个新属性,它将存储文档的_id,但作为字符串而不是 ObjectId

    类似的东西

    db.site.aggregate([
      {
        $addFields: {
          siteIdString: { // this is the stringified version of the _id
            $toString: "$_id"
          }
        }
      },
      {
        $lookup: {
          from: "setting",
          localField: "siteIdString", // then use this string id in lookup stage
          foreignField: "site_id",
          as: "setting"
        }
      }
    ])
    

    你可以在这里测试Mongo Playground2

    希望对你有帮助

    【讨论】:

    • @MohammedYoursy 不幸的是,我无法控制架构,它是供应商提供的软件。有没有办法检查和查看字段的类型?
    • 我已经更新了将 test_id 作为字符串处理的答案,你能检查一下吗?
    猜你喜欢
    • 2020-05-16
    • 2020-07-15
    • 1970-01-01
    • 1970-01-01
    • 2020-09-13
    • 2011-04-29
    • 1970-01-01
    • 2011-05-25
    • 2016-06-30
    相关资源
    最近更新 更多