我有书的名称,描述,出版商ObjectID字段,作者ID数组,类别ID字段等收集我需要搜索名称,描述,出版商名称,作者和$regex类别名称的书。
要在聚合管道中实现这一点,我首先使用$lookup填充authors、publisher、categories,然后在字段上使用带有$or运算符的$match。
我的查询工作,但它执行非常缓慢(约11秒),其中图书收集只包含7万个文档。
在集合模型、索引或查询中需要哪些步骤才能获得良好的性能?
书本型号:
{
"_id" : ObjectId("5a2934934410bf8b0e547989"),
"publisher" : ObjectId("5a27e7b68021772210b125d4"),
"is_enabled" : true,
"published_at" : ISODate("2017-12-07T12:31:15.166Z"),
"author" : [
ObjectId("5a27c5754b0efc477f37a131"),
ObjectId("5a27c5754b0efc47737a1512"),
ObjectId("5a27c5754b0efc477f37a145"),
],
"category" : [
ObjectId("5a27e22ffb6110b11c326cd7"),
ObjectId("5a27e22ffb6110b11c326ced"),
ObjectId("5a27e22ffb6110b11c326d2d"),
ObjectId("5a27e22ffb6110b11c326e45")
]
"published_year" : "2017"
}
质询I执行:
Book.aggregate(
[
{
$match: {
"is_enabled": { $eq: true },
}
},
{
$lookup:
{
from: "authors",
localField: "author",
foreignField: "_id",
as: "author"
}
},
{
$lookup:
{
from: "categories",
localField: "category",
foreignField: "_id",
as: "category"
}
},
{
$lookup:
{
from: "publishers",
localField: "publisher",
foreignField: "_id",
as: "publisher"
}
},
{
$match: {
$or: [
{ "author.name": new RegExp(params.expression, 'i') },
{ "category.name": new RegExp(params.expression, 'i') },
{ "publisher.name": new RegExp(params.expression, 'i') },
{ "description": new RegExp(params.expression, 'i') },
{ "name": new RegExp(params.expression, 'i') },
{ "published_year": params.terms }
]
}
},
{
$project: {
previous_price: "$previous_price",
price: "$price",
name: "$name",
seo_url: "$seo_url",
click_url: "book",
author: "$author",
authorObj: {
name: { $arrayElemAt: ["$author.name", 0] },
}
}
},
{ $sort: { name: 1 } }
]
)
.skip(8 * (params.pagenum - 1))
.limit(8)
.exec((err, product) => {
if (err)
reject(err);
else
resolve(product);
})
1条答案
按热度按时间jdgnovmf1#
您可以为字段
is_enabled, author, category and publisher
创建索引,如下所示。这将提高第一匹配阶段和查找的性能。
您也可以为
name, description and published_year
创建索引,但我不确定该索引对最后匹配阶段的影响,因为您使用了$or
条件。据我所知,仍然无法优化使用$or, $in
的索引查询(〈=3.2)。您可以尝试一下。如果您使用$and
条件查询,这会很有帮助。如果您使用$and
查询,则还可以创建***多键索引***对于name, description and published_year
。类似然后在匹配条件中遵循相同的顺序