$ lookup两个级别

时间:2019-01-27 13:14:34

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

我是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可以实现。
也欢迎进行查询以获取所描述格式的数据!
谢谢!

1 个答案:

答案 0 :(得分:2)

您可以在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"
  }}
])