简体   繁体   English

简化MongoDB聚合

[英]Simplify MongoDB aggregation

I'm using such aggregation to sort all products by deep nested field ObjectId.我正在使用这种聚合按深层嵌套字段 ObjectId 对所有产品进行排序。

At first I populate catalogProduct field.首先,我填充 catalogProduct 字段。

Then populate category inside catalogProduct.然后在目录产品中填充类别。

Sort all data by category Id (return product if ids arr includes category._id)按类别 ID 对所有数据进行排序(如果 ids arr 包括 category._id,则返回产品)

Sort in reverse order, returns page and limit by 8 for pagination.逆序排序,返回页码,分页限制为 8。

Then getting total count of all sorted products without paginatin and limit.然后在没有分页和限制的情况下获得所有排序产品的总数。

 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

I'm getting such data:我得到这样的数据:

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

And It's fine.这很好。 But I think, that aggregation can be simplified, and i don't need to repeat operations to get total count, but I don't know how.但我认为,聚合可以简化,我不需要重复操作来获得总数,但我不知道如何。

You can observe the starting stages until $match by catalogProduct.category._id is repeated in the 2 $facet .您可以观察开始阶段,直到$match by catalogProduct.category._id在 2 $facet重复。 Therefore, you can simply factor them out, then put the afterwards stages into $facet respectively.因此,您可以简单地将它们分解,然后将之后的阶段分别放入$facet

Below is my suggested version of your code:以下是我建议的代码版本:

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"},
        ]
        }},
]);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM