文档菜单
文档首页
/
MongoDB 手册
/ / /

复合索引排序顺序

本页内容

  • 用例
  • 示例
  • 排行榜支持索引
  • 反向结果
  • 不支持查询
  • 了解更多

索引存储字段引用,顺序为升序(1)或降序(-1)。对于复合索引,排序顺序可以确定索引是否支持排序操作。

复合索引支持与索引排序顺序或索引逆排序顺序匹配的排序操作。

一个手机游戏有一个排行榜,显示以下信息

  • 最高游戏分数

  • 达到每个分数的用户

  • 每个分数的达成日期

应用程序首先按 分数 降序排序排行榜。然后,与每个 分数 关联的 用户名 按升序(字母顺序)排序。

如果索引中的排序顺序与查询中的排序顺序匹配,则复合索引可以提高排行榜的性能。

考虑一个包含以下文档的 排行榜 集合

db.leaderboard.insertMany( [
{
"score": 50,
"username": "Alex Martin",
"date": ISODate("2022-03-01T00:00:00Z")
},
{
"score": 55,
"username": "Laura Garcia",
"date": ISODate("2022-03-02T00:00:00Z")
},
{
"score": 60,
"username": "Alex Martin",
"date": ISODate("2022-03-03T00:00:00Z")
},
{
"score": 60,
"username": "Riya Patel",
"date": ISODate("2022-03-04T00:00:00Z")
},
{
"score": 50,
"username": "Laura Garcia",
"date": ISODate("2022-03-05T00:00:00Z")
}
] )

此查询返回排行榜结果

db.leaderboard.find().sort( { score: -1, username: 1 } )

输出

[
{
_id: ObjectId("632235700646eaee87a56a74"),
score: 60,
username: 'Alex Martin',
date: ISODate("2022-03-03T00:00:00.000Z")
},
{
_id: ObjectId("632235700646eaee87a56a75"),
score: 60,
username: 'Riya Patel',
date: ISODate("2022-03-04T00:00:00.000Z")
},
{
_id: ObjectId("632235700646eaee87a56a73"),
score: 55,
username: 'Laura Garcia',
date: ISODate("2022-03-02T00:00:00.000Z")
},
{
_id: ObjectId("632235700646eaee87a56a72"),
score: 50,
username: 'Alex Martin',
date: ISODate("2022-03-01T00:00:00.000Z")
},
{
_id: ObjectId("632235700646eaee87a56a76"),
score: 50,
username: 'Laura Garcia',
date: ISODate("2022-03-05T00:00:00.000Z")
}
]

结果首先按分数降序排序,然后按用户名升序(字母顺序)排序。

以下索引通过使索引的排序顺序与查询中使用的排序顺序相匹配,提高了排行榜结果的性能

db.leaderboard.createIndex( { score: -1, username: 1 } )

这个复合索引存储

  • score值,按照降序排列。

  • username值,按照升序(字母顺序)排列。

MongoDB可以双向遍历复合索引。如果应用程序允许用户以反向顺序查看排行榜,该索引也支持该查询。

以下查询以反向顺序返回排行榜,其中结果首先按升序score值排序,然后按降序username值(反向字母顺序)排序

db.leaderboard.find().sort( { score: 1, username: -1 } )

输出

[
{
_id: ObjectId("632235700646eaee87a56a76"),
score: 50,
username: 'Laura Garcia',
date: ISODate("2022-03-05T00:00:00.000Z")
},
{
_id: ObjectId("632235700646eaee87a56a72"),
score: 50,
username: 'Alex Martin',
date: ISODate("2022-03-01T00:00:00.000Z")
},
{
_id: ObjectId("632235700646eaee87a56a73"),
score: 55,
username: 'Laura Garcia',
date: ISODate("2022-03-02T00:00:00.000Z")
},
{
_id: ObjectId("632235700646eaee87a56a75"),
score: 60,
username: 'Riya Patel',
date: ISODate("2022-03-04T00:00:00.000Z")
},
{
_id: ObjectId("632235700646eaee87a56a74"),
score: 60,
username: 'Alex Martin',
date: ISODate("2022-03-03T00:00:00.000Z")
}
]

索引{ score: -1, username: 1 }支持此查询。

复合索引不支持排序顺序与索引或索引的反向不匹配的查询。因此,索引{ score: -1, username: 1 }不支持按升序score值和按升序username值排序,例如此查询

db.leaderboard.find().sort( { score: 1, username: 1 } )

此外,为了使排序操作使用索引,排序中指定的字段必须以与索引中相同的顺序出现。因此,上述索引不支持此查询

db.leaderboard.find().sort( { username: 1, score: -1, } )

返回

创建

© . This site is unofficial and not affiliated with MongoDB, Inc.