简化MongoDB聚合

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

首先我填充CatalogProduct字段。

然后填充CatalogProduct内的类别。

按类别ID对所有数据排序(如果ID arr包含类别._id,则返回product)

按相反顺序排序,返回分页并按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] ] }
]

而且很好。但我认为,聚合可以简化,我不需要重复操作来获得总计数,但我不知道如何进行。


解决方案

可以观察起始阶段,直到2中重复$matchbycatalogProduct.category._id。因此,您可以简单地将它们提取出来,然后将后续阶段分别放入$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"},
        ]
        }},
]);

相关文章