【问题标题】:MongoDb like query with sort performance具有排序性能的类似 MongoDb 的查询
【发布时间】:2026-01-03 10:55:01
【问题描述】:

我正在使用 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”。这个查询很费时间。有什么办法可以优化查询吗?

【问题讨论】:

  • posts 是一个数组吗?
  • 可以提供文件样本吗?
  • @willis,没有帖子有整数值。
  • @matthPen 下面是示例文档。 {“_id”:NumberInt(8596321),“fname”:“Harth”,“lname”:“jose”,“imgpath”:“”,“imgname”:“”,“status”:“A”,“posts " : 7.0, "os" : 1.0 }

标签: regex mongodb performance sorting aggregation-framework


【解决方案1】:
  1. 如果您查看您的匹配:{$match :{$and:[{os : {$in:[0,1]}}, {_id : {$nin : [3,10]}}]}},您可以看到您正在尝试匹配 os_id - 如果您尝试匹配 _id,您通常会想要在您的索引中包含_id
  2. 在下一个 $match 中,您尝试在 fnamelname 上进行匹配——如果没有编入索引,这会很慢(而且 OR 通常很难编入索引)。这似乎是查询中基数最高的部分。
  3. 您实际上并未在此管道中使用任何聚合特定功能!您可以改为将其编写为常规查询并使用投影和限制。您还在不需要的地方使用$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} 这样的表现应该会更好。

【讨论】: