【问题标题】:How to display name with the id but with datas in 2 collections MongoDb?如何使用 id 显示名称但使用 2 个集合 MongoDb 中的数据?
【发布时间】:2019-11-14 09:34:37
【问题描述】:

我只想通过相应的名称更改 ID。但是 id 在一个集合中,而 name 在其他集合中。 "$lookup" Mongo 在我的情况下不起作用...

第一个集合“参数”包含具有“category_id”的项目:

{"_id" : ObjectId("56cc8827b9e4ed0fd42a4569"), 
    "data" : {
        "capacity" : NumberInt(60), 
        "categories" : [
            {
                "category_id" : "5964961294ff4a37988e8f9b", 
                "nbMax" : NumberInt(1), 
                "nbRes" : NumberInt(0)
            }, 
            {
                "category_id" : "596495c994ff4a37988e8f99", 
                "nbMax" : NumberInt(1), 
                "nbRes" : NumberInt(0)
            }, 
        ], 
      }, 
    "type" : "launcher", 
    "name" : "launcherp01", 
    "description" : "", 
    "_class" : "parameter"
}
....

{ 
    "_id" : ObjectId("56cc8827b9e4ed0fd42a4847"),
    "data" : {
        "capacity" : NumberInt(60), 
        "categories" : [
            {
                "category_id" : "596495c994ff4a37988e8f99", 
                "nbMax" : NumberInt(1), 
                "nbRes" : NumberInt(0)
            }, 
            {
                "category_id" : "8864961294ff4a37988e8f3b", 
                "nbMax" : NumberInt(1), 
                "nbRes" : NumberInt(0)
            }, 
        ], 
      }, 
    "type" : "launcher", 
    "name" : "launcherp01", 
    "description" : "", 
    "_class" : "parameter"
}
.....

第二个集合“参考”包含对具有 _id(与第一个集合中的 category_id 相同)和 名称 的类别的描述强>:

{
   "_id" : ObjectId("596495c994ff4a37988e8f99"), 
    "taskType" : "qc", 
    "type" : "category", 
    "name" : "**qcSupportNormal01**", 
    "_class" : "reference", 
}

{ 
    "_id" : ObjectId("5964961294ff4a37988e8f9b"),
    "taskType" : "transcode", 
    "type" : "category", 
    "name" : "tsSupportNormal01", 
    "_class" : "reference", 
}

我想要类似的东西(类别名称而不是id的项目):

  { 
        "_id" : ObjectId("56cc8827b9e4ed0fd42a4569"), 
        "type" : "launcher", 
        "categories" : [
            "qcSupportNormal01", //--->> name from reference collection
            "tsSupportNormal01", //--->> name from reference collection
    }     

    { 
        "_id" : ObjectId("56cc8827b9e4ed0fd42a4847"), 
        "type" : "launcher", 
        "categories" : [
            "qcSupportNormal01", //--->> name from reference collection
            "qptestNormal01",    //--->> name from reference collection
    ...

我的查询:

db.parameters.aggregate([
///////////////////////item filter
    {$match: {
      type:{ $in: [ "launcher" ] } ,
    }},  
///////////////////// foreign field      
    {$lookup: {
            from: "references",
            localField: "categories",
            foreignField: "_id",
            as: "references"
    }},
/////////////////// projection 
    {$project:
        {_id:1,type:1,categories:"$data.categories.category_id"
    }},
])

但结果始终是 id 而不是名称:

{ 
    "_id" : ObjectId("56cc8827b9e4ed0fd42a4569"), 
    "type" : "launcher", 
    "categories" : [
        "5964961294ff4a37988e8f9b", //--->> id not name from reference collection !
        "596495c994ff4a37988e8f99", //--->> id not name from reference collection !
       ...

如何使用类别名称而不是 id。 在 Sql 中非常简单(与外键和引用表联合)但在 Mongo 查询中很复杂......

感谢您的帮助

je déteste le langage Mongo!

【问题讨论】:

  • 请在 jsoneditor 分享收藏和您想要收藏的内容

标签: mongodb


【解决方案1】:

您的方法存在几个问题:

  1. 您正在尝试在 ObjectIdstring 值之间调用 $lookup
  2. 对于您的categories 字段,您将其映射到来自data.categoriescategory_id,而它应该来自references.name
  3. category_id 字段嵌套在数组中,当您调用 $lookup 时,您将其与整个数组而不是 key 字段匹配。

因此,现在最好的方法是将字段category_id 转换为ObjectId,然后为该字段调用$lookup我没有修改实际字段,而是添加了一个名为作为cat_id)。

我会这样做:

db.parameter.aggregate([    
{
    $match: {
        type: { $in: ["launcher"] },
    }
},
{ $unwind: "$data.categories" },
{ $addFields: { "data.categories.cat_id": { $convert: { input: "$data.categories.category_id", to: "objectId" } } } },
{
    $lookup: {
        from: "references",
        localField: "data.categories.cat_id",
        foreignField: "_id",
        as: "ref"
    }
},
{
    $project:
        {
            _id: 1, type: 1, categories: "$ref.name"
        }
}
]);

这会给你一个输出:

{
"_id" : ObjectId("56cc8827b9e4ed0fd42a4569"),
"type" : "launcher",
"categories" : [
    "tsSupportNormal01"
]
},
{
"_id" : ObjectId("56cc8827b9e4ed0fd42a4569"),
"type" : "launcher",
"categories" : [
    "**qcSupportNormal01**"
]
},
{
"_id" : ObjectId("56cc8827b9e4ed0fd42a4847"),
"type" : "launcher",
"categories" : [
    "**qcSupportNormal01**"
]
},
{
"_id" : ObjectId("56cc8827b9e4ed0fd42a4847"),
"type" : "launcher",
"categories" : [ ]
}

【讨论】:

  • 谢谢 vikscool,但我在 Mongo 3.4 上,$convert 从 mongo 4.0 开始就存在。我在 3.4 中寻找对象的强制转换字符串。
  • @caloux 我建议将 MongoDB 升级到最新或至少 v4.0(所以,您可以使用更多有用的功能)。如果不可能,您可能必须编写一个脚本来执行类似于 1 的流程的输出。创建一个包含所有类别的数组 name 及其 _idstring 中,然后是来自 @987654340 的另一个数组@ 和 filter=' launcher',然后在 parameter obj 上执行 foreach 循环,并附加类别数组中的匹配值。
  • @vikscool 感谢您的反馈,我将更新到 v4.0,更好地提供有用的功能。
猜你喜欢
  • 2019-02-28
  • 1970-01-01
  • 1970-01-01
  • 2017-04-19
  • 2020-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-15
相关资源
最近更新 更多