我正在使用mongodb 3.6,其中有Usermst集合,其中包含用户文档。我将获取更多帖子的用户名和姓氏。以下是我的mongodb查询。
db.getCollection("UserMst").aggregate([
{$match :{$and:[{os : {$in:[0,1]}}, {_id : {$nin : [3,10]}}]}}
,{$match:{$and:
[ {$or: [
{$and : [{fname:{$regex : `^has.*` , $options: 'i' }},{lname:{$regex : `^pa.*` , $options: 'i' }}]}
,{$and: [{fname:{$regex : `^pa.*` , $options: 'i' }}, {lname:{$regex : `^has.*` , $options: 'i' }}]}
]}
]
}
}
,{$sort:{'posts':-1,'_id':-1}}
,{$project:{"fname":1,"lname":1,"posts":1}}
,{$limit:5}
])
我的索引为“名称”:“ os_1_posts_-1”。该查询很耗时。有什么方法可以优化查询?
答案 0 :(得分:0)
{$match :{$and:[{os : {$in:[0,1]}}, {_id : {$nin : [3,10]}}]}}
,可以看到您正在尝试在os
和_id
上进行匹配-如果您尝试在_id上进行匹配,您通常会希望在索引中使用_id
。fname
或lname
上进行匹配-如果未建立索引,这将很慢(并且OR通常很难建立索引)。看来这可能是基数最高的查询的一部分。$and
您的聚合管道的查询类似于:
{
os: {$in: [0, 1] },
_id : {$nin : [3,10]},
$or: [
{
fname: { $regex: `^has.*` , $options: 'i' },
lname:{ $regex: `^pa.*` , $options: 'i' }
},
{
fname: {$regex : `^pa.*` , $options: 'i' },
lname:{$regex : `^has.*` , $options: 'i'
}
]
}
然后依次在posts
和_id
上排序
我不确定哪个字段的基数最大,您的数据是什么样的以及在此数据库上正在运行的其他查询是什么,因此很难推荐实际的索引,但是很难找到一个复合索引像{lname, fname, os, posts, _id}
应该表现更好。