mongodb聚合条件$ lookup管道性能

时间:2019-07-13 06:01:43

标签: mongodb

我进行了聚合查询,如下所示。此查询的工作原理很好,并生成我想要的数据。我想问的是这样的聚合在性能方面特别好,尤其是在条件$lookup这样的管道中使用管道?

ReactiveAggregate(this, Product, [
            {$match: {slug}},
            {$lookup: {
                from: 'suppliers',
                let: {supplierId: '$supplier_id'},
                pipeline: [
                    {
                        $match: {
                            $expr: {
                                $eq: ['$_id', '$$supplierId']
                            }
                        }
                    },
                    {
                        $lookup: {
                            from: 'addresses',
                            let: {supplierAddress: '$address'},
                            pipeline: [
                                {
                                    $match: {
                                        $expr: {
                                            $eq: ['$_id', '$$supplierAddress']
                                        }
                                    }
                                }
                            ],
                            as: 'address'
                        }
                    },
                    {$unwind: {path: '$address', preserveNullAndEmptyArrays: false}},
                    {
                        $lookup: {
                            from: 'supplier_assets',
                            let: {supplierId: '$_id'},
                            pipeline: [
                                {
                                    $match: {
                                        $expr: {
                                            $and: [
                                                {$eq: ['$meta.supplier_id', '$$supplierId']},
                                                {$eq: ['$meta.type', 'logo']}
                                            ]
                                        }
                                    }
                                }
                            ],
                            as: 'logo'
                        }
                    },
                    {$unwind: {path: '$logo', preserveNullAndEmptyArrays: false}},
                    {
                        $lookup: {
                            from: 'products',
                            let: {supplierId: '$_id'},
                            pipeline: [
                                {
                                    $match: {
                                        $expr: {
                                            $and: [
                                                {$eq: ['$supplier_id', '$$supplierId']},
                                                {$eq: ['$isApproved', true]}
                                            ]
                                        }
                                    },
                                },
                                {
                                    $limit: 5
                                },
                                {$project: {
                                    name: 1,
                                    slug: 1,
                                    supplier_id: 1,
                                    variantMaster: {
                                        $filter: {
                                            input: '$variants',
                                            as: 'variantMaster',
                                            cond: {$eq: ['$$variantMaster.is_master', true]}
                                            }
                                        }
                                    }
                                },
                                {$unwind: {path: '$variantMaster', preserveNullAndEmptyArrays: true}},
                                {
                                    $lookup: {
                                        from: 'product_assets',
                                        let: {variantMasterId: '$variantMaster._id'},
                                        pipeline: [
                                            {
                                                $match: {
                                                    $expr: {
                                                        $or: [
                                                            {
                                                                $and: [
                                                                    {$eq: ['$meta.variant_id', '$$variantMasterId']},
                                                                    {$eq: ['$meta.is_primary', true]}
                                                                ]
                                                            },
                                                            {
                                                                $eq: ['$meta.variant_id', '$$variantMasterId'],
                                                            }
                                                        ]
                                                    }
                                                }
                                            },
                                        ],
                                        as: 'images'
                                    }
                                },
                                {$lookup: {
                                    from: 'product_sale',
                                    let: {productId: '$_id'},
                                    pipeline: [
                                        {
                                        $match: {
                                            $expr: {
                                            $and: [
                                                {$eq: ['$product_id', '$$productId']},
                                                {$gt: ['$end_date', new Date()]},
                                                {$lte: ['$start_date', new Date()]},
                                                {$eq: ['$active', true]},
                                                {$eq: ['$approved', true]},
                                            ]
                                            }
                                        }
                                        },
                                    ],
                                  as: 'sale'
                                }},
                                {
                                    $project:{
                                        name: 1,
                                        slug: 1,
                                        supplierName: '$supplier.name',
                                        price: '$variantMaster.price',
                                        sale: {$arrayElemAt: ['$sale', 0]},
                                        image: {$arrayElemAt: ['$images', 0]}
                                    }
                                }
                            ],
                            as: 'relatedProducts'
                        }
                    },
                    {
                        $project: {
                            name: 1,
                            url: 1,
                            relatedProducts: 1,
                            logo: 1,
                            city: '$address.city',
                            state: '$address.state',
                        }
                    }
                ],
                as: 'supplier'
            }},
            {
                $unwind: '$supplier'
            },
            {$project: {
                name: 1,
                slug: 1,
                supplier: 1,
                variants: 1,
                description: 1,
                variantMaster: {
                    $filter: {
                        input: '$variants',
                        as: 'variantMaster',
                        cond: {$eq: ['$$variantMaster.is_master', true]}
                        }
                    }
                }
            },
            {
                $unwind: '$variantMaster'
            },
            {
                $lookup: {
                    from: 'product_assets',
                    localField: 'variantMaster._id',
                    foreignField: 'meta.variant_id',
                    as: 'images'
                }
            },
            {
                $lookup: {
                    from: 'product_sale',
                    let: {productId: '$_id'},
                    pipeline: [
                        {
                        $match: {
                            $expr: {
                            $and: [
                                {$eq: ['$product_id', '$$productId']},
                                {$gt: ['$end_date', new Date()]},
                                {$lte: ['$start_date', new Date()]},
                                {$eq: ['$active', true]},
                                {$eq: ['$approved', true]},
                            ]
                            }
                        }
                        },
                    ],
                  as: 'sale'
                },
            },
            {
                $unwind: {path: '$sale', preserveNullAndEmptyArrays: true}
            },
            {
                $lookup: {
                    from: 'stock',
                    localField: 'variantMaster.stock',
                    foreignField: '_id',
                    as: 'stock'
                }
            },
            {
                $unwind: {path: '$stock', preserveNullAndEmptyArrays: true}
            },
            {
                $lookup: {
                    from: 'product_review',
                    let: {productId: '$_id'},
                    pipeline: [
                        {
                            $match: {
                                $expr: {$eq: ['$product_id', '$$productId']}
                            },
                        },
                        {
                            $lookup: {
                                from: 'user_data',
                                let: {reviewProfileId: '$user_profile_id'},
                                pipeline: [
                                    {
                                        $match: {
                                            $expr: {$eq: ['$_id', '$$reviewProfileId']}
                                        }
                                    },
                                    {
                                        $lookup: {
                                            from: 'avatar',
                                            let: {profileId: '$_id'},
                                            pipeline: [
                                                {
                                                    $match: {
                                                        $expr: {$eq: ['$meta.profile_id', '$$profileId']}
                                                    }
                                                }
                                            ],
                                            as: 'avatar'
                                        }
                                    },
                                    {
                                        $project: {
                                            user_id: 1,
                                            avatar: {$arrayElemAt: ['$avatar', 0]},
                                        }
                                    }
                                ],
                                as: 'user'
                            }
                        },
                        {$unwind: {path: '$user', preserveNullAndEmptyArrays: true}},
                        {
                            $project: {
                                user: 1,
                                rating: 1,
                                review: 1,
                                user_fullname: 1,
                                postedAt: 1,
                                owner_reply: 1,
                                repliedAt: 1,
                            }
                        }
                    ],
                    as: 'reviews'
                }
            },
            {
                $lookup: {
                    from: 'favorited_products',
                    let: {productId: '$_id'},
                    pipeline: [
                        {
                            $match: {
                                $expr: {
                                    $and: [
                                        {$eq: ['$product_id', '$$productId']},
                                        {$eq: ['$user_id', this.userId]}
                                    ]
                                }
                            }
                        }
                    ],
                    as: 'favorite'
                }
            },
            {
                $unwind: {path: '$favorite', preserveNullAndEmptyArrays: true}
            },
            {
                $project: {
                    name: 1,
                    images: 1,
                    description: 1,
                    price: '$variantMaster.price',
                    variantMaster: 1,
                    supplier: 1,
                    is_ready_stock: 1,
                    is_custom: 1,
                    is_culinary: 1,
                    slug: 1,
                    reviews: 1,
                    sale: 1,
                    variants: 1,
                    stock: 1,
                    favorite: 1,
                }
            }
        ])

这是我从mongo shell获得的日志

"executionStats" : {
    "executionSuccess" : true,
    "nReturned" : 1,
    "executionTimeMillis" : 5,
    "totalKeysExamined" : 1,
    "totalDocsExamined" : 1,
        // rest..

确保速度很快,因为仅返回了1个数据,但是如果返回100或1000个数据该怎么办。我还在学习mongodb。请分享在mongodb中进行聚合查询的利弊。进行聚合查询时有什么好的方法?我知道我可以参考此页面optimize aggregation pipeline

谢谢。

0 个答案:

没有答案