首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >聚合文档多级

聚合文档多级
EN

Stack Overflow用户
提问于 2018-06-05 21:32:20
回答 1查看 51关注 0票数 0

现在考虑一下这个例子,我有一个文档,包含下面的类似集合的结构。下面是订单集合

代码语言:javascript
复制
{

        "_id" : ObjectId("5788fcd1d8159c2366dd5d93"), 
        "color" : "Blue", 
        "code" : "1", 
        "category_id" : ObjectId("5693d170a2191f9020b8c815"), 
        "description" : "julia tried", 
        "name" : "Order1", 
        "brand_id" : ObjectId("5b0e52f058b8287a446f9f05")

}

还有一个Brand和Category集合。这是类别集合

代码语言:javascript
复制
{ 
"_id" : ObjectId("5693d170a2191f9020b8c815"), 
"name" : "Category1", 
"created_at" : ISODate("2016-01-11T20:32:17.832+0000"), 
"updated_at" : ISODate("2016-01-11T20:32:17.832+0000"), 
}

品牌收藏

代码语言:javascript
复制
{ 
   "_id" : ObjectId("5b0e52f058b8287a446f9f05"), 
   "name" : "brand1", 
   "description" : "brand1", 
   "updated_at" : ISODate("2017-07-05T09:18:13.951+0000"), 
   "created_at" : ISODate("2017-07-05T09:18:13.951+0000"), 
}

在应用聚合之后,现在应该会产生以下格式:

代码语言:javascript
复制
{
    'brands': [
             {
                _id: '*******'
                name: 'brand1',

                categories: [
                   {
                      _id: '*****',
                      name: 'category_name1',
                      orders: [
                          {
                              _id: '*****',
                              title: 'order1'
                          }

                      ]

                   }
                ]
             }
     ]
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-06-06 00:40:07

你可以尝试下面的聚合:

代码语言:javascript
复制
db.brand.aggregate([
    {
        $lookup: {
            from: "order",
            localField: "_id",
            foreignField: "brand_id",
            as: "orders"
        }
    },
    {
        $unwind: "$orders"
    },
    {
        $lookup: {
            from: "category",
            localField: "orders.category_id",
            foreignField: "_id",
            as: "categories"
        }
    },
    {
        $unwind: "$categories"
    },
    {
        $group: {
            _id: "$_id",
            name: { $first: "$name" },
            description: { $first: "$description" },
            updated_at: { $first: "$updated_at" },
            created_at: { $first: "$created_at" },
            categories: { $addToSet: "$categories" },
            orders: { $addToSet: "$orders" }
        }
    },
    {
        $addFields: {
            categories: {
                $map: {
                    input: "$categories",
                    as: "category",
                    in: {
                        $mergeObjects: [ 
                            "$$category", { 
                                orders: [ { 
                                    $filter: { 
                                        input: "$orders", 
                                        as: "order", 
                                        cond: { $eq: [ "$$category._id", "$$order.category_id" ] } 
                                    } 
                                } ]
                         } ]
                    }
                }
            }
        }
    },
    {
        $project: {
            orders: 0
        }
    }
])

基本上,您必须使用$lookup两次才能根据brand_idcategory_id字段“合并”所有这些集合中的数据。由于您期望在brandscategories中使用orders,因此可以对这两个数组使用$unwind,然后使用$group获得以下形状:

代码语言:javascript
复制
{
    "_id" : ObjectId("5b0e52f058b8287a446f9f05"),
    "name" : "brand1",
    "description" : "brand1",
    "updated_at" : ISODate("2017-07-05T09:18:13.951Z"),
    "created_at" : ISODate("2017-07-05T09:18:13.951Z"),
    "categories" : [
            {
                    "_id" : ObjectId("5693d170a2191f9020b8c814"),
                    "name" : "Category1",
                    "created_at" : ISODate("2016-01-11T20:32:17.832Z"),
                    "updated_at" : ISODate("2016-01-11T20:32:17.832Z")
            }
    ],
    "orders" : [
            {
                    "_id" : ObjectId("5788fcd1d8159c2366dd5d93"),
                    "color" : "Blue",
                    "code" : "1",
                    "category_id" : ObjectId("5693d170a2191f9020b8c814"),
                    "description" : "julia tried",
                    "name" : "Order1",
                    "brand_id" : ObjectId("5b0e52f058b8287a446f9f05")
            }
    ]
}

现在,您有了brand1及其所有子类别,以及应该放在其中一个类别中的所有订单。唯一的问题是如何在categories中“嵌套”orders。要做到这一点,一种方法可能是$map,您可以将每个类别与匹配该类别的所有订单合并(使用$mergeObjects,您不必指定categories对象中的所有属性)。

要将categoryorders匹配,您可以在orders阵列上执行$filter

然后,您可以删除orders,因为它们嵌套在类别中,因此您不再需要它们。

编辑: 3.4版本

在MongoDB 3.4中,你不能使用$mergeObjects,所以你应该指定``categories的所有属性:

代码语言:javascript
复制
db.brand.aggregate([
    {
        $lookup: {
            from: "order",
            localField: "_id",
            foreignField: "brand_id",
            as: "orders"
        }
    },
    {
        $unwind: "$orders"
    },
    {
        $lookup: {
            from: "category",
            localField: "orders.category_id",
            foreignField: "_id",
            as: "categories"
        }
    },
    {
        $unwind: "$categories"
    },
    {
        $group: {
            _id: "$_id",
            name: { $first: "$name" },
            description: { $first: "$description" },
            updated_at: { $first: "$updated_at" },
            created_at: { $first: "$created_at" },
            categories: { $addToSet: "$categories" },
            orders: { $addToSet: "$orders" }
        }
    },
    {
        $addFields: {
            categories: {
                $map: {
                    input: "$categories",
                    as: "category",
                    in: {
                        _id: "$$category._id",
                        name: "$$category.name",
                        created_at: "$$category.created_at",
                        updated_at: "$$category.updated_at",
                        orders: [ 
                            { 
                                $filter: { 
                                    input: "$orders", 
                                    as: "order", 
                                    cond: { $eq: [ "$$category._id", "$$order.category_id" ] } 
                                } 
                            } 
                        ]
                    }
                }
            }
        }
    },
    {
        $project: {
            orders: 0
        }
    }
])
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50701420

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档