【问题标题】:Simplify MongoDB aggregation简化 MongoDB 聚合
【发布时间】:2021-12-15 03:29:10
【问题描述】:

我正在使用这种聚合按深层嵌套字段 ObjectId 对所有产品进行排序。

首先我填充 catalogProduct 字段。

然后在 catalogProduct 中填充类别。

按类别 ID 对所有数据进行排序(如果 ids arr 包含 category._id,则返回产品)

倒序排列,返回page,分页限制为8。

然后得到所有排序产品的总数,没有分页和限制。

const sortedProducts = await StorageModel.aggregate([
                // Unite products arr and totalCount of sorted products
                {$facet: {
                    "sortedProducts": [
                        // populate catalogProduct ref by Id
                        { $lookup: {
                                from: "catalogs",
                                localField: "catalogProduct",
                                foreignField: "_id",
                                as: "catalogProduct"
                            } },
                        // deconstruct this Arr, because we get only one Object
                        { $unwind: "$catalogProduct" },
                        // populate category ref by Id inside catalogProduct object
                        { $lookup: {
                                from: "categories",
                                localField: "catalogProduct.category",
                                foreignField: "_id",
                                as: "catalogProduct.category"
                            } },
                        // deconstruct this Arr, because we get only one Object
                        { $unwind: "$catalogProduct.category" },
                        // returns product, if ids arr includes a catalogProduct.category._id
                        { $match: {
                                "catalogProduct.category._id": { $in: ids }
                            } },
                        // sort in reverse order
                        { $sort: { _id: -1 } },
                        // returns only *page
                        { $skip: (page - 1) * 8 },
                        /// limit result by 8
                        { $limit: 8 },
                    ],
                    // total count for pagination, the same operations
                    "totalCount": [
                        { $lookup: {
                                from: "catalogs",
                                localField: "catalogProduct",
                                foreignField: "_id",
                                as: "catalogProduct"
                            } },
                        { $unwind: "$catalogProduct" },
                        { $lookup: {
                                from: "categories",
                                localField: "catalogProduct.category",
                                foreignField: "_id",
                                as: "catalogProduct.category"
                            } },
                        { $unwind: "$catalogProduct.category" },
                        { $match: {
                                "catalogProduct.category._id": { $in: ids }
                            } },
                        // get total count of sorted data, without limit and pagination
                        {$count : "totalCount"},
                    ]
                    }},
            ]);
            
            products = sortedProducts[0].sortedProducts
            totalProducts = sortedProducts[0].totalCount.totalCount

我正在获取这样的数据:

[
  { sortedProducts: [ [Object], [Object] ], totalCount: [ [Object] ] }
]

而且没关系。但我认为,聚合可以简化,我不需要重复操作来获得总数,但我不知道如何。

【问题讨论】:

    标签: javascript database mongodb mongoose query-optimization


    【解决方案1】:

    您可以观察开始阶段,直到 $match by catalogProduct.category._id 在 2 $facet 中重复。因此,您可以简单地将它们分解出来,然后将之后的阶段分别放入$facet

    以下是我建议的代码版本:

    StorageModel.aggregate([
        { $lookup: {
            from: "catalogs",
            localField: "catalogProduct",
            foreignField: "_id",
            as: "catalogProduct"
        } },
        // deconstruct this Arr, because we get only one Object
        { $unwind: "$catalogProduct" },
        // populate category ref by Id inside catalogProduct object
        { $lookup: {
                from: "categories",
                localField: "catalogProduct.category",
                foreignField: "_id",
                as: "catalogProduct.category"
            } },
        // deconstruct this Arr, because we get only one Object
        { $unwind: "$catalogProduct.category" },
        // returns product, if ids arr includes a catalogProduct.category._id
        { $match: {
            "catalogProduct.category._id": { $in: ids }
        } },
        // Unite products arr and totalCount of sorted products
        {$facet: {
            "sortedProducts": [
                // populate catalogProduct ref by Id
                
                // sort in reverse order
                { $sort: { _id: -1 } },
                // returns only *page
                { $skip: (page - 1) * 8 },
                /// limit result by 8
                { $limit: 8 },
            ],
            // total count for pagination, the same operations
            "totalCount": [
                // get total count of sorted data, without limit and pagination
                {$count : "totalCount"},
            ]
            }},
    ]);
    

    【讨论】:

      猜你喜欢
      • 2022-08-13
      • 2018-02-18
      • 2021-06-02
      • 2021-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-09
      • 2017-02-08
      相关资源
      最近更新 更多