一、单值索引排序
如果在单个字段上是升序或降序索引,则对该字段的排序操作可以是任一方向。
例如,在字段a上为收集记录创建一个升序索引:
db.records.createIndex( { a: 1 } )
该索引可以支持对以下内容的升序排序:
db.records.find().sort( { a: 1 } )
通过以相反的顺序遍历索引,索引还可以支持以下对a的降序排序:
db.records.find().sort( { a: -1 } )
二、复合索引排序
您可以在索引的所有键或子集上指定排序; 但是,排序键必须按照它们在索引中出现的顺序列出。
例如:
#索引键模式{a:1,b:1}
#支持
db.records.find().sort( {a:1,b:1} )
#不支持
db.records.find().sort( {a:1,b:-1} )
为了使查询使用复合索引进行排序,文档中所有键的指定排序方向必须与索引键模式匹配或与索引键模式的反方向匹配。
例如:
#索引键模式{a:1,b:-1}
#支持
db.records.find().sort( {a:1,b:-1} )
db.records.find().sort( {a:-1,b:1} )
#不支持
db.records.find().sort( {a:-1,b:-1} )
db.records.find().sort( {a:1,b:1} )
三、排序和索引前缀
索引前缀 是一个复合索引(compound index)的一个子集,它是由索引的起始字段开始的一个或多个 key 组成。
比如,在 data 表上创建了一个复合索引:
db.data.createIndex( { a:1, b: 1, c: 1, d: 1 } )
那么,下面的这些就是这个索引的前缀:
{ a: 1 }
{ a: 1, b: 1 }
{ a: 1, b: 1, c: 1 }
以下查询和排序操作使用索引前缀对结果进行排序,这些操作不需要对内存中的结果集进行排序:
考虑以下示例,其中索引的前缀键同时出现在find和sort中:
db.data.find({a:{$ gt:4}}).sort({a:1,b:1})
在这种情况下,MongoDB可以使用索引按排序指定的顺序检索文档。 如示例所示,find中的索引前缀可以与sort中的前缀不同。
四、排序和索引非前缀子集
一个索引可以在索引字段规则的非前缀子集上支持排序操作,但前提是,查询条件必须在索引字段中的排序字段之前所有的前缀字段上包含const条件。
比如,在 data 表上创建了一个复合索引:
db.data.createIndex( { a:1, b: 1, c: 1, d: 1 } )
下面的操作可以使用索引获取到排序顺序:
正如上面最后一条操作所示,在 sort 字段子集前的索引字段必须在检索文档上有等价条件;其他的索引字段可以指定其他的条件。
如果在搜索条件上没有指定位于 sort 字段前或覆盖 sort 字段的索引前缀字段上的等价条件,那么这个操作将 不能有效地 利用这个索引。
例如,下面的操作指定了按 {c: 1} 排序文档,但搜索条件不包含位于索引字段前面字段 a 和 b 的等价匹配:
db.data.find({a:{$ gt:2}}).sort({c:1})#无法利用索引
db.data.find({c:5}).sort({c:1})#无法利用索引
这些操作将不能有效地利用索引 { a: 1, b: 1, c: 1, d: 1 } 并且甚至不能使用到索引。