我需要一些关于在mongo中创建和排序索引的建议。
我有一个包含5个属性的帖子集合:
帖子
几乎所有帖子都具有相同的状态1,只有少数会有拒绝状态。我的所有查询都将过滤状态,开始和结束日期,并对sortOrder进行排序。我还将有一个查询在标题上进行正则表达式搜索。
我应该在{status:1,start:1,end:1,sort:1}上设置复合键吗?将字段放在复合索引中的顺序是否重要 - 我应该将状态放在复合索引中,因为它是最广泛的吗?在每个属性上做复合索引而不是单个索引是否更好? mongo只对任何给定的查询使用单个索引吗?
如果我正在对此进行正则表达式查询,那么对于lowerCaseTitle的索引是否有任何提示?
示例查询是:
db.posts.find({status: {$gte:0}, start: {$lt: today}, end: {$gt: today}}).sort({sortOrder:1})
db.posts.find( {lowerCaseTitle: /japan/, status:{$gte:0}, start: {$lt: today}, end: {$gt: today}}).sort({sortOrder:1})
答案 0 :(得分:16)
在一篇文章中有很多问题;)让我按实际顺序浏览它们:
所以,你根本不应该在索引中包含状态,因为一旦索引遍历消除了基于更高基数字段的绝大多数文档,它在大多数情况下最多会留下2-3个文档,这些文档几乎没有被优化状态索引(特别是因为你提到这2-3个文档很可能具有相同的状态)。
现在,与您的案例相关的最后一个注释是,当您使用范围查询(并且您是)时,它仍然不会使用索引进行排序。您可以在测试查询后查看explain()的“scanAndOrder”值来检查这一点。如果该值存在且为true,则表示它将在内存中排序结果集(扫描和顺序),而不是直接使用索引。在您的具体情况下,这是无法避免的。
因此,您的索引应为:
db.posts.ensureIndex({start:1, end:1})
和您的查询(为了清晰起见,修改了订单,查询优化器将通过相同的执行路径运行您的原始查询,但我更喜欢首先按顺序放置索引字段):
db.posts.find({start: {$lt: today}, end: {$gt: today}, status: {$gte:0}}).sort({sortOrder:1})