我进行了聚合查询,如下所示。此查询的工作原理很好,并生成我想要的数据。我想问的是这样的聚合在性能方面特别好,尤其是在条件$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
谢谢。