【问题标题】:$lookup two levels$lookup 两层
【发布时间】:2019-06-20 15:49:33
【问题描述】:

我是 MongoDB 和 NoSQL 的新手,我正在尝试感受(在相当有限的时间内)它是否可以为我们已经将数据作为 json 文件的快速演示项目完成工作。 我正在尝试使用 Mongo 测试不同的查询场景,并且有一种情况我被卡住了。 想象一下,我有 3 个 mongodb 集合,代表具有类别和子类别的产品。每个项目可能有许多类别,每个类别可能有许多子类别。 下面是一个简单的数据示例:

产品

{ "id" : "1", "name" : "product1", "categories": ["cat1_id", "cat2_id"] }
{ "id" : "2", "name" : "product2", "categories": ["cat1_id"]}
{ "id" : "3", "name" : "product3", "categories": ["cat3_id"}

类别

{ "id" : "cat1_id", "name" : "cat1", "sub_categories": ["subcat1_id", "scat2_id"]}
{ "id" : "cat2_id", "name" : "cat2", "sub_categories": ["subcat3_id"]}
{ "id" : "cat3_id", "name" : "cat3", "sub_categories": ["subcat1_id"]}

子类别

{ "id" : "subcat1_id", "name" : "sub cat1"}
{ "id" : "subcat2_id", "name" : "sub cat2"}
{ "id" : "subcat3_id", "name" : "sub cat3"}

我正在尝试查找 3 个集合,以便将类别和子类别的数据获取到产品文档中:

{ 
  "id" : "1", 
  "name" : "product1", 
  "categories": [{
    "id": "cat1_id", 
    "name": "cat1", 
    "sub_categories": [
      { "id" : "subcat1_id", "name" : "sub cat1"}
      { "id" : "subcat2_id", "name" : "sub cat2"}
    ]
  }, {
    "id": "cat2_id", 
    "name": "cat2", 
    "sub_categories": [
      { "id" : "subcat1_id", "name" : "sub cat1"}
    ]
  }]
}

我正在进行 2 次查找并尝试了多个展开选项,但如果产品有 2 个类别,我总是只获得第一个类别的子类别详细信息 - 第二个类别的子类别的详细信息消失了,即使是第 2 类,我也得到第 1 类的子类别。

这是我得到的查询和结果:

查询:

db.product.aggregate([
    $lookup: {
        from: "category",
        localField: "categories",
        foreignField: "id",
        as: "categories_obj"
    },
    $unwind: "categories",
    $unwind: "categories_obj.sub_categories",
    $lookup: {
        from: "sub_category",
        localField: "categories_obj.sub_categories",
        foreignField: "id",
        as: "sub_category_obj"
    }
])

结果:

{
  "id" : "1", 
  "name" : "product1",
  "categories": "cat1_id"
  "categories_obj" : [
     { "id" : "cat1_id", "name" : "cat1", "sub_categories": ["subcat1_id", 
     "scat2_id"]}
     { "id" : "cat2_id", "name" : "cat2", "sub_categories": ["subcat3_id"]}
  ],
  "sub_category_obj": [
     { "id" : "subcat1_id", "name" : "sub cat1"}
     { "id" : "subcat2_id", "name" : "sub cat2"}
  ]
}
{
  "id" : "1", 
  "name" : "product1",
  "categories": "cat2_id"
  "categories_obj" : [
     { "id" : "cat1_id", "name" : "cat1", "sub_categories": ["subcat1_id", 
     "scat2_id"]}
     { "id" : "cat2_id", "name" : "cat2", "sub_categories": ["subcat3_id"]}
  ],
  "sub_category_obj": [
     { "id" : "subcat1_id", "name" : "sub cat1"}
     { "id" : "subcat2_id", "name" : "sub cat2"}
  ]
}

从结果中可以看出,cat1 和 cat2 都显示了子类别 1 和 2(属于 cat1)的详细信息,但缺少子类别 3(属于 cat2)。 一旦我能够获取所有子类别的详细信息,我将尝试通过 $group、$project 等获取上述所需的数据格式,但我不知道如何获取所有子类别详细信息.

请在这件事上给予我帮助。我希望 MongoDB 可以实现。
能够以所述格式获取数据的查询也将受到欢迎!
谢谢!

【问题讨论】:

    标签: arrays mongodb join mongodb-query aggregation-framework


    【解决方案1】:

    您可以将以下聚合与 mongodb 3.6 及更高版本一起使用

    Project.aggregate([
      { "$lookup": {
        "from": Category.collection.name,
        "let": { "categories": "$categories" },
        "pipeline": [
          { "$match": { "$expr": { "$in": [ "$_id", "$$categories" ] } } },
          { "$lookup": {
            "from": SubCategory.collection.name,
            "let": { "sub_categories": "$sub_categories" },
            "pipeline": [
              { "$match": { "$expr": { "$in": [ "$_id", "$$sub_categories" ] } } }
            ],
            "as": "sub_categories"
          }}
        ],
        "as": "categories"
      }}
    ])
    

    【讨论】:

    • 这就像一个魅力!非常感谢,我什至没有考虑使用管道。我应该更详细地了解管道,看起来非常强大的功能。再次感谢您的帮助!
    猜你喜欢
    • 2020-05-09
    • 2019-05-12
    • 1970-01-01
    • 2019-05-02
    • 2019-01-28
    • 1970-01-01
    • 1970-01-01
    • 2023-01-17
    • 1970-01-01
    相关资源
    最近更新 更多